【发布时间】:2019-12-19 13:29:22
【问题描述】:
尝试将此作为问题发布在 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 上的升级项目中。
【问题讨论】:
-
在 EF Core 3 中,拥有的类型现在可以为 null,如果它们没有任何必填字段。自动映射器是否已更新以应对这种语义变化?
-
您是在询问 AutoMapper 本身是否已更新?据我所知,应该没有必要,因为检查执行计划表明它将处理
null拥有的实体。如果您的意思是我应该更新我的 AutoMapper 配置,您能看出我遗漏了什么? -
SomeEntity的PK在哪里?它是否包含在SomeEntityForm中?请更新帖子中的代码,以便重现问题。 -
更新了主键字段。表单中没有
Id不会影响映射。 -
在我的测试中它确实很重要。另外,关于
var entity = …;- 您是否从上下文中检索实体并使用跟踪查询,即实体是否附加到上下文?请包含完整的可重现示例,使用 EF Core,每个细节都很重要。
标签: c# entity-framework-core automapper