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);