使用AutoMapper更新拥有实体上的属性不会将其设置为Modified

问题描述 投票:-1回答:1

[尝试将其作为问题发布在AutoMapper的GitHub上,但尚未关闭并在此处指出。

在EF Core 3.1中,使用AutoMapper更新拥有类型的实体不会触发EF Core的更改检测。

此问题在EF Core 2.2中不存在。

源/目的地类型

public class SomeOwnedType
{
    public string SomeString { get; set; }
}
public class SomeEntity
{
    [Key]
    public int Id { get; set; }
    public SomeOwnedType Something { get; set; } = new SomeOwnedType();
    public DateTime? UpdatedAt { get; set; }
}
public class SomeEntityForm
{
    public int Id { get; set; }
    public SomeOwnedType Something { get; set; } = new SomeOwnedType();
    public DateTime? UpdatedAt { get; set; }
}
public class MyContext : IdentityDbContext<...>
{
    public DbSet<SomeEntity> Entities { get; set; }
    protected override void OnModelCreating(ModelBuilder builder) =>
        builder.Entity<SomeEntity>().OwnsOne(e => e.Something);
}

映射配置

CreateMap<SomeEntity, SomeEntityForm>()
    .ReverseMap()
    .ForMember(dest => dest.UpdatedAt, opt => opt.Ignore())
    .ForMember(dest => dest.Something, opt => opt.UseDestinationValue());

CreateMap<SomeOwnedType, SomeOwnedType>();

版本:EF Core 3.1上的9.0.0

AutoMapper集合5.0.0

AutoMapper扩展Microsoft DependencyInjection 7.0.0

预期行为

public async Task<IActionResult> SomeAction([FromForm] SomeEntityForm form)
{
    var entity = await context.Entities.FirstOrDefaultAsync();
    if (entity == null)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        mapper.Map(form, entity);
        entity.UpdatedAt = DateTime.Now;

        context.Entities.Update(entity);

        var changes = context.ChangeTracker.Entries();
        // entity -> Modified
        // entity.Something -> Modified

        return Ok();
    }

    return BadRequest();
}

实际行为

var form = ...; // Something.SomeString = "qwerty"
var entity = ...; // Something.SomeString = "abcde"

mapper.Map(form, entity);
// entity.Something.SomeString = "qwerty"

context.Entities.Update(entity);

var changes = context.ChangeTracker.Entries();
// entity -> Modified
// no entry for entity.Something

复制步骤

同上Expected behaviour

偶然地,手动修改该字段会将期望的实体标记为已修改:

var entity = ...; // Something.SomeString = "qwerty"

entity.Something.SomeString = "abcde";

context.Entities.Update(entity);

var changes = context.ChangeTracker.Entries();
// entity -> Modified
// entity.Something -> Modified

奇怪的是,在完全启动的.NET Core 3.1项目中不会发生此问题,而只会在以前在.NET Core 2.2上的升级项目中出现。

c# entity-framework-core automapper
1个回答
0
投票

我对此问题的“解决方案是:

  • 使用迁移在相同类型的父项上创建另一个拥有的财产
  • 使用另一个迁移将数据从原始列复制到新列中
  • 使用另一个迁移删除旧列
  • 使用另一个迁移将新列重命名为旧列

这很可怕,远非理想,但它有效,我没有其他问题了。

© www.soinside.com 2019 - 2024. All rights reserved.