c# – 实体框架核心:无法使用嵌套值对象更新实体
我有一个具有值对象的实体,该值对象具有另一个值对象.我的问题是,在更新实体和值对象时,具有父值对象的实体会更新,但子值对象不会更新.
请注意,我使用了最新版本的Entity Framework Core 2.1.0-rc1-final 这是父实体Employee public class Employee : Entity { public string FirstName { get; private set; } public string LastName { get; private set; } public string Email { get; private set; } public Address Address { get; private set; } } 这是父值对象Address public class Address : ValueObject<Address> { private Address() { } public Address(string street,string city,string state,string country,string zipcode,GeoLocation geoLocation) { Street = street; City = city; State = state; Country = country; ZipCode = zipcode; GeoLocation = geoLocation; } public string Street { get; private set; } public string City { get; private set; } public string State { get; private set; } public string Country { get; private set; } public string ZipCode { get; private set; } public GeoLocation GeoLocation { get; private set; } } 这是子值对象GeoLocation public class GeoLocation { private GeoLocation() { } public GeoLocation(decimal longitude,decimal latitude) { Latitude = latitude; Longitude = longitude; } public Decimal Longitude { get; private set; } public Decimal Latitude { get; private set; } } 在更新员工时,我首先从数据库中获取它,然后使用从用户界面获取的新值更改Address属性 var employee = _repository.GetEmployee(empId); employee.SetAddress(newAddress); 和SetAddress方法 public void SetAddress(Address address) { Guard.AssertArgumentNotNull(address,nameof(address)); Address = address; } 解决方法
根据
this EF Core GitHub ticket,您必须直接更新子/嵌套/拥有类型属性才能正确跟踪它.这应该在EF 2.1中修复(目前仅作为候选版本提供)但可能尚未完成.在2.0.3中,他们将例外的措辞更新为:
如果您使用DDD,此消息的第二部分将使您稍微呕吐.它告诉您必须直接为EF更新子/嵌套属性的属性以正确跟踪更改(这会将DDD值对象分解为不可变).根据comment on the GitHub thread,这是一个建议的,有些DDD友好,适合您的代码匹配的变通方法: public void SetAddress(Address address) { Guard.AssertArgumentNotNull(address,nameof(address)); Address.UpdateFrom(address); } // And on Address: internal void UpdateFrom(Address other) { Street = other.Street; // ... } -要么- 第二个建议的解决方法是通过分离实体,更新Address的实例,然后重新附加它来完成的.在我的实现中,我对这个解决方法没有太多运气,但会将其发布给后代.也许你会比我更幸运. context.Entry(employee.Address).State = EntityState.Detached; employee.SetAddress(newAddress); context.Entry(employee.Address).State = EntityState.Modified; UPDATE 我终于找到了EF Core团队的开放票,可以跟踪此问题. Ticket #10551具体说明了手头的问题,仍然是开放的.它肯定没有进入EF Core 2.1,似乎已被放置在Backlog Milestone 3.0中.请注意,您可以对此问题进行投票,以便让EF Core团队更加关注它. 更新2 internal void Upsert(object entity) { ChangeTracker.TrackGraph(entity,e => { if (e.Entry.IsKeySet) { e.Entry.State = EntityState.Modified; } else { e.Entry.State = EntityState.Added; } }); #if DEBUG foreach (var entry in ChangeTracker.Entries()) { Debug.WriteLine($"Entity: {entry.Entity.GetType().Name} State: {entry.State.ToString()}"); } #endif } 然后,使用context.Upsert(< YOUR ENTITY OBJECT>);在context.SaveChanges();之前. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |