首页 > 解决方案 > 仅在使用 Dapper 更新时忽略属性?

问题描述

设置

作为我的数据访问层的一部分,我将 Dapper 与 DapperExtensions 一起使用,并用模型表示我的数据库实体。其中一些模型包含用于记录或更改跟踪的字段,如下所示:

public class ExampleClass : BaseModel, ITypeWithChangeTracking
{
    public int ExampleClassId { get { return Id; } set { Id = value; } }
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }

    // More properties
}

public class ExampleClassMapper : ClassMapper<ExampleClass>
{
    public ExampleClassMapper() : base()
    {
        Map(m => m.ExampleClassId).Key(KeyType.Identity);
        Map(m => m.Id).Ignore();
        base.AutoMap();
    }
}

在此示例中,BaseModel 是一个抽象类,它指定模型具有一些整数 Id(以便更容易使用泛型);ITypeWithChangeTracking 指定它应该具有更改跟踪字段。到目前为止,我已经能够将大部分 DAL 逻辑改组为可以在所有模型之间共享的通用实现,并且我希望与那些实现更改跟踪的模型保持同步。

使用的工具

C#

小巧玲珑

DapperExtensions

问题

某些更改跟踪字段应在插入对象时设置,而不是在更新对象时设置。我无法以可用于每个模型的通用方式实现这一点。

问题

有什么我可以与 Dapper 或 DapperExtensions 一起使用来指定一个字段应该包含在插入中,但忽略更新?

我已经查看了各种属性,例如用于映射的 ReadOnly 和 Ignore,但到目前为止,我发现的所有内容都是“始终包含”或“始终忽略”的笼统。最好,我希望它可以与标准的 Update() 函数一起使用,并且不需要专门的存储过程,尽管我不确定这是否可能。我缺少任何漏洞或有用的装饰器吗?

(注意:如果有办法将这个规范一直打乱到 ITypeWithChangeTracking 接口,那么主要的布朗尼点!)


编辑:

我没有创建单独的模型,而是调整了已经从 ITypeWithChangeTracking 设置更改跟踪值的代码,以便它能够识别未设置的值(null、DateTime.Min 等)。它已经在检查记录是新的还是以前存在的,所以如果 1) 记录确实存在并且 2) 模型具有未设置的更改跟踪值,我让它从现有记录中获取相关值。

标签: c#dapperdapper-extensions

解决方案


正如我在评论中提到的,要走的路是为 UPDATE 创建单独的类,其中不包含您要为 UPDATE 忽略的属性。您可能不需要每次都创建单独的类;您可以重用您的视图模型或类似的。

其他解决方案是回退到 Dapper 绕过 Dapper Extensions。有了这个,你现在有多种选择,因为 Dapper 更加灵活。您可以选择传递匿名对象或动态参数来仅更新您要更新的属性。

类似的讨论已经在这里这里完成。


推荐阅读