我有一个项目,我在使用DDD方法后使用Asp.Net Core 2.0。因此,我拥有聚合根,它拥有实体和值对象,这些对象被配置为拥有类型,这是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跟踪的实体更新价值对象(拥有实体)?
答案 0 :(得分:1)
我在使用ef core 1.0.0时找到了解决方法。我再次找不到引用将链接放在这里并将作品提供给作者,但在您的情况下,解决方法将是这样的:
<强> DOMAIN 强>:
django.__main__
EF核心实体配置:
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...
}
需要覆盖DbContext
中的SaveChanges()<强>的DbContext:强>
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
}
}
如果ef core 2.0拥有的实体像EF6.X复杂类型一样工作以实现DDD值对象,那将是很好的。此解决方法将需要一些猴子工作代码,但您将能够应用DDD。