ServiceStack 的 Ormlite 删除不工作
ServiceStack's Ormlite Delete not working
我创建了一个通用存储库来在 MVC 项目中进行 CRUD 操作。
当我尝试从 table 中删除在 SQL 服务器上具有标识的行时,由 Ormlite Delete
方法生成并使用探查器检查的代码没有'不会影响任何行。
这是删除的Crud操作(很简单):
public void Destroy<T>(T entity)
{
using (var db = dbFactory.Open())
{
db.Delete<T>(entity);
}
}
我测试中的类型 T
由以下 class 表示:
[Alias("FT_TEST_DEVELOPMENT")]
public class TestTable
{
[AutoIncrement]
[PrimaryKey]
public int ID { get; set; }
public string DESCR { get; set; }
public DateTime? TIMESTAMP { get; set; }
public DateTime DATE { get; set; }
public decimal PRICE { get; set; }
public int? QTY { get; set; }
}
而检查到的代码对应如下:
exec sp_executesql N'DELETE FROM "FT_TEST_DEVELOPMENT" WHERE "ID"=@ID AND "DESCR"=@DESCR AND "TIMESTAMP"=@TIMESTAMP AND "DATE"=@DATE AND "PRICE"=@PRICE AND "QTY"=@QTY ',
N'@ID int,@DESCR nvarchar(6),@TIMESTAMP datetime,@DATE datetime,@PRICE decimal(2,0),@QTY int',
@ID=4,@DESCR=N'SECOND',@TIMESTAMP=NULL,@DATE='2015-06-01 00:00:00',@PRICE=15,@QTY=NULL
当我执行这个完美感知的语句时,服务器告诉我没有行
免责声明:由于有些名字是我的母语,所以我翻译了它们,所以可能会有一些语法错误,如果是这样,让我注意,我会编辑。
更新
数据库中实际存在匹配的行
SELECT * 来自 FT_TEST_DEVELOPMENT 其中 ID= 4
ID 描述 时间戳 日期 价格 数量
4 第二个 NULL 2015-06-01 15 NULL
我的意思是实际上 OrmLite 生成的代码似乎有问题。
是的,ID 列是 table 的键。
第二次更新
我想我已经找到原因了:
实际上在 WHERE
子句中 NULL 字段以
的方式分配
@TIMESTAMP=NULL
但实际上 SQL 服务器不会匹配此语句,因为它希望收到
WHERE [...] AND "TIMESTAMP" IS NULL [...]
如果您在 SSMS 中执行相同的语句但没有删除任何内容,那是因为没有行符合条件。
OrmLite 期望实体的主键被命名为 Id
(区分大小写)。您的 属性 名为 ID
并且未指定 [PrimaryKey]
属性。在这种情况下,OrmLite 必须使用 WHERE
子句中的所有可用字段来查找要删除的行。
AutoIncrement
并不意味着该字段是键,只是它的值是由服务器自动生成的并且来自标识列。这同样适用于 SQL 服务器 - 标识列不是主键,您需要单独定义主键。
您需要将 ID
重命名为 Id
或为其添加 [PrimaryKey]
属性。
db.Delete()
API 的工作方式 has been updated so that NULL
fields are moved out of the parameterized queries and appended to the SQL filter so this should now work from v4.0.37+ that's now available on MyGet。
您还可以通过主键删除 OrmLite 中的行:
Db.DeleteById<TestTable>(entity.Id);
对于通用方法,您可以使用 T.GetId()
扩展方法来获取 Id 字段的值,即:
Db.DeleteById<TestTable>(entity.GetId());
或者在 DELETE
WHERE 条件中使用每个 non null
属性 删除,您可以使用:
Db.DeleteNonDefaults(entity);
我创建了一个通用存储库来在 MVC 项目中进行 CRUD 操作。
当我尝试从 table 中删除在 SQL 服务器上具有标识的行时,由 Ormlite Delete
方法生成并使用探查器检查的代码没有'不会影响任何行。
这是删除的Crud操作(很简单):
public void Destroy<T>(T entity)
{
using (var db = dbFactory.Open())
{
db.Delete<T>(entity);
}
}
我测试中的类型 T
由以下 class 表示:
[Alias("FT_TEST_DEVELOPMENT")]
public class TestTable
{
[AutoIncrement]
[PrimaryKey]
public int ID { get; set; }
public string DESCR { get; set; }
public DateTime? TIMESTAMP { get; set; }
public DateTime DATE { get; set; }
public decimal PRICE { get; set; }
public int? QTY { get; set; }
}
而检查到的代码对应如下:
exec sp_executesql N'DELETE FROM "FT_TEST_DEVELOPMENT" WHERE "ID"=@ID AND "DESCR"=@DESCR AND "TIMESTAMP"=@TIMESTAMP AND "DATE"=@DATE AND "PRICE"=@PRICE AND "QTY"=@QTY ',
N'@ID int,@DESCR nvarchar(6),@TIMESTAMP datetime,@DATE datetime,@PRICE decimal(2,0),@QTY int',
@ID=4,@DESCR=N'SECOND',@TIMESTAMP=NULL,@DATE='2015-06-01 00:00:00',@PRICE=15,@QTY=NULL
当我执行这个完美感知的语句时,服务器告诉我没有行
免责声明:由于有些名字是我的母语,所以我翻译了它们,所以可能会有一些语法错误,如果是这样,让我注意,我会编辑。
更新
数据库中实际存在匹配的行
SELECT * 来自 FT_TEST_DEVELOPMENT 其中 ID= 4 ID 描述 时间戳 日期 价格 数量 4 第二个 NULL 2015-06-01 15 NULL
我的意思是实际上 OrmLite 生成的代码似乎有问题。
是的,ID 列是 table 的键。
第二次更新 我想我已经找到原因了:
实际上在 WHERE
子句中 NULL 字段以
@TIMESTAMP=NULL
但实际上 SQL 服务器不会匹配此语句,因为它希望收到
WHERE [...] AND "TIMESTAMP" IS NULL [...]
如果您在 SSMS 中执行相同的语句但没有删除任何内容,那是因为没有行符合条件。
OrmLite 期望实体的主键被命名为 Id
(区分大小写)。您的 属性 名为 ID
并且未指定 [PrimaryKey]
属性。在这种情况下,OrmLite 必须使用 WHERE
子句中的所有可用字段来查找要删除的行。
AutoIncrement
并不意味着该字段是键,只是它的值是由服务器自动生成的并且来自标识列。这同样适用于 SQL 服务器 - 标识列不是主键,您需要单独定义主键。
您需要将 ID
重命名为 Id
或为其添加 [PrimaryKey]
属性。
db.Delete()
API 的工作方式 has been updated so that NULL
fields are moved out of the parameterized queries and appended to the SQL filter so this should now work from v4.0.37+ that's now available on MyGet。
您还可以通过主键删除 OrmLite 中的行:
Db.DeleteById<TestTable>(entity.Id);
对于通用方法,您可以使用 T.GetId()
扩展方法来获取 Id 字段的值,即:
Db.DeleteById<TestTable>(entity.GetId());
或者在 DELETE
WHERE 条件中使用每个 non null
属性 删除,您可以使用:
Db.DeleteNonDefaults(entity);