ServiceStack的Ormlite删除无法正常工作

时间:2015-01-15 15:47:24

标签: c# servicestack ormlite-servicestack

我已经组建了一个通用存储库来在MVC项目中进行CRUD操作。

当我尝试从SQLServer上具有标识的表中删除行时,Ormlite Delete方法生成并使用分析器检查的代码不会影响任何行。

这是删除的Crud操作(非常简单):

    public void Destroy<T>(T entity)
    {
        using (var db = dbFactory.Open())
        {
            db.Delete<T>(entity);
        }
    }

我的测试中的类型T由以下类表示:

[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

当我执行这个完美感知的语句时,服务器告诉我没有行

免责声明:有些名字在我的母语中,我翻译了它们,因此可能没有语法错误,如果是这样的话,请注意,我会编辑。

更新

匹配的行实际上是数据库中的EXISTS

SELECT * FROM FT_TEST_DEVELOPMENT WHERE ID = 4    ID DESCR TIMESTAMP日期价格数量    4 SECOND NULL 2015-06-01 15 NULL

我的意思是实际上OrmLite生成的代码似乎被窃听了。

是的,ID列是表的密钥。

第二次更新 我想我找到了原因:

实际上在WHERE子句中,NULL字段以

的方式分配
@TIMESTAMP=NULL

但实际上SQL服务器与此语句不匹配,因为它希望接收

WHERE [...] AND "TIMESTAMP" IS NULL [...]

2 个答案:

答案 0 :(得分:2)

db.Delete() API的工作方式has been updated,以便NULL字段移出参数化查询并附加到SQL过滤器,因此现在可以使用 v4.0.37 + 现在available on MyGet

您还可以使用以下方法删除OrmLite中的行:

Db.DeleteById<TestTable>(entity.Id);

对于通用方法,您可以使用T.GetId()扩展方法获取Id字段的值,即:

Db.DeleteById<TestTable>(entity.GetId());

或者要使用null WHERE条件中的每个 DELETE属性进行删除,您可以使用:

Db.DeleteNonDefaults(entity);

答案 1 :(得分:1)

如果在SSMS中执行相同的语句并且没有任何内容被删除,那是因为没有符合条件的行。

OrmLite期望实体的主键名为Id(区分大小写)。您的属性名为ID,未指定[PrimaryKey]属性。在这种情况下,OrmLite必须使用WHERE子句中的所有可用字段来查找要删除的行。

AutoIncrement并不意味着该字段是一个键,只是它的值由服务器自动生成并来自标识列。这同样适用于SQL Server - 标识列不是主键,您需要单独定义主键。

您需要将ID重命名为Id或向其添加[PrimaryKey]属性。