c# – 如何在DDD方法之后更新EF Core 2.0拥有的实体?
发布时间:2020-12-15 22:47:30 所属栏目:百科 来源:网络整理
导读:我有一个项目,我使用Asp.Net Core 2.0遵循DDD方法.因此,我拥有聚合根,它拥有实体和值对象,这些对象被配置为拥有类型,这是EF Core 2.0中的一项新功能.我已经添加了这样的配置示例以更好地阐明. 域: public class Address : ValueObject { public Address(str
我有一个项目,我使用Asp.Net Core 2.0遵循DDD方法.因此,我拥有聚合根,它拥有实体和值对象,这些对象被配置为拥有类型,这是EF Core 2.0中的一项新功能.我已经添加了这样的配置示例以更好地阐明.
域: public class Address : ValueObject { public Address(string street,int number){ Street = street; Number = number; } public string Street {get; private set;} public int Number {get; private set;} } public class Company : AggregateRoot { public Address Address {get; private set;} // Other properties... // Value objects are immutables so I'm only able to replace it with a new object. public void UpdateAddress(string street,int number){ Address = new Address(street,number); } // Other methods... } EF核心实体配置: internal class CompanyEntityTypeConfiguration : IEntityTypeConfiguration<Company> { public void Configure(EntityTypeBuilder<Company> builder) { builder.HasKey(x => x.Id); builder.OwnsOne(x => x.Address); } } 我正在从数据库中检索跟踪实体,当我尝试更新AggregateRoot替换一个新的值对象时,我得到一个异常,说“已经跟踪了另一个相同类型的实体”.地址是被跟踪的实体. 因此,解决方案是检索未跟踪但我不想使用此方法,因为它将在数据库中进行完全更新.那么,如何从Entity Framework 2.0跟踪的实体更新值对象(拥有实体)? 解决方法
当我使用ef core 1.0.0时,我找到了一个解决方法.我再次找不到引用将链接放在此处并将作品提供给作者,但在您的情况下,解决方法将是这样的:
域: public class Address : ValueObject { public Address(string street,int number) { Street = street; Number = number; } public string Street { get; private set; } public int Number { get; private set; } #region Value object workaround public Address WithStreet(string value) => new Address(value,Number); public Address WithNumber(int value) => new Address(Street,value); #endregion } public class Company : AggregateRoot { #region public public Address Address { get; set; } [NotMapped] public Address Address { get; set; } //In the DbContext this property needs to be mapped with a column in a database private string Address_Street { get { return Address.Street; } set { Address = Address.WithStreet(value); } } //In the DbContext this property needs to be mapped with a column in a database private int Address_Number { get { return Address.Number; } set { Address = Address.WithNumber(value); } } #endregion // Other properties... // Value objects are immutables so I'm only able to replace it with a new object. public void UpdateAddress(string street,int number) { Address = new Address(street,number); } // Other methods... } EF核心实体配置: internal class CompanyEntityTypeConfiguration : IEntityTypeConfiguration<Company> { public void Configure(EntityTypeBuilder<Company> builder) { #region Address value object workaround builder.Property(typeof(string),"Address_Street").HasColumnName("Address_Street"); builder.Property(typeof(int),"Address_Number").HasColumnName("Address_Number"); #endregion } } 需要覆盖DbContext中的SaveChanges() 的DbContext: public class YourDbContext : DbContext { //yours DbSet<> protected override void OnModelCreating(ModelBuilder builder) { //yours EntityTypeConfiguration } /// <summary> /// Overridden for value object workaround /// </summary> /// <returns></returns> public override int SaveChanges() { foreach (var entry in ChangeTracker.Entries()) { foreach (var pi in entry.Entity.GetType().GetProperties(BindingFlags.Instance | BindingFlags.NonPublic)) { entry.Property(pi.Name).CurrentValue = pi.GetValue(entry.Entity); } } return base.SaveChanges(); } } 如果ef core 2.0拥有的实体像EF6.X复杂类型一样工作以实现DDD值对象,那将是很好的.此解决方法将需要一些猴子工作代码,但您将能够应用DDD. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |