为啥要在 UpdateAsync 上设置 CreationTime 和 CreatorUserId?

Posted

技术标签:

【中文标题】为啥要在 UpdateAsync 上设置 CreationTime 和 CreatorUserId?【英文标题】:Why are CreationTime and CreatorUserId getting set on UpdateAsync?为什么要在 UpdateAsync 上设置 CreationTime 和 CreatorUserId? 【发布时间】:2018-04-25 17:23:05 【问题描述】:

我正在调用UpdateAsync,但它正在更新CreationTimeCreatorUserId 列,即使我没有传递这些值。它应该只更新所需的列。


  "testCode": "string",
  "testName": "string",
  "testDesc": "string",
  "id": 1

public async Task UpdateTest(TestDetailsDTO input)

    var classobj = ObjectMapper.Map<Test>(input);
    await UpdateAsync(classobj);

public class TestDetailsDTO : FullAuditedEntityDto

    public string TestCode  get; set; 
    public string TestName  get; set; 
    public string TestDesc  get; set; 

参数inputUpdateTest服务方法中获取CreationTime

public class Test : FullAuditedEntity

    public const int NVarcharLength20 = 20;
    public const int NVarcharLength30 = 30;
    public const int NVarcharLength50 = 50;

    [Required]
    [MaxLength(NVarcharLength20)]
    public virtual string TestCode  get; set; 

    [Required]
    [MaxLength(NVarcharLength30)]
    public virtual string TestName  get; set; 

    [MaxLength(NVarcharLength50)]
    public virtual string TestDesc  get; set; 

【问题讨论】:

【参考方案1】:

当前流量:

    ObjectMapper.Map&lt;Test&gt;(input) 创建一个新的 Test 对象。 CreationTimeCreatorUserIddefault(DateTime)default(long?)。 ABP 设置这些值。

正确的流程:

    从数据库中获取classobj。 恢复CreationTimeCreatorUserId。 将input 映射到classobj

var classobj = repository.GetEntity(input.id); // 1
input.CreationTime = classobj.CreationTime;    // 2
input.CreatorUserId = classobj.CreatorUserId;  // 2
ObjectMapper.Map(input, classobj);             // 3

更好的设计:

不要为 input 继承 FullAuditedEntityDto → 跳过第 2 步。

它正在工作,还有其他方法吗?因为它调用了额外的 GetEntity 方法。

另一种方式是attach。权衡是您必须明确映射,而不是 ObjectMapper.Map

// Create new stub with correct id and attach to context.
var classobj = new Test  Id = input.Id ;
repository.As<EfRepositoryBase<MyDbContext, Test>>().Table.Attach(classobj);

// Now the entity is being tracked by EF, update required properties.
classobj.TestCode = input.TestCode;
classobj.TestName = input.TestName;
classobj.TestDesc = input.TestDesc;

// EF knows only to update the properties specified above.
_unitOfWorkManager.Current.SaveChanges();

【讨论】:

以上是关于为啥要在 UpdateAsync 上设置 CreationTime 和 CreatorUserId?的主要内容,如果未能解决你的问题,请参考以下文章

为啥要在 CAKeyframeAnimation 上使用 `keyTimes`、`timingFunctions` 或 `timingFunction`?

为啥要在标记点击事件上重新渲染地图?

为啥要在堆上而不是栈上分配内存? [复制]

为啥我们要在对数尺度上搜索 RidgeCV alpha?

为啥要在包上使用许多子项目和依赖项?

在使用 JPA 映射类时,为啥有人要在 getter 或 setter 上添加注释?