我使用一个value对象来表示Price
public record Price(decimal Amount, string Currency);
那么我有两个价格
的实体public class Item
{
public Price { get; private set; }
// rest of properties
}
public class OrderPosition
{
public Price { get; private set; }
// rest
}
在DB中,我希望有这两个表
Items
| Id | Price_Amount | Price_Currency |
OrderPositions
| Id | Price_Amount | Price_Currency |
为了实现这一点,我将价格配置为商品的拥有类型以及订单位置:
public class ItemConfiguration : IEntityTypeConfiguration<Item>
{
public void Configure(EntityTypeBuilder<Item> builder)
{
builder.OwnsOne(i => i.Price);
}
}
public class ItemConfiguration : IEntityTypeConfiguration<OrderPosition>
{
public void Configure(EntityTypeBuilder<OrderPosition> builder)
{
builder.OwnsOne(op => op.Price);
}
}
这一切都很好,但是当我在一个项目上有相同的价格以及订单位置时,EF会给我一个警告:
[09:47:59 WRN] The same entity is being tracked as different entity types 'Item.Price#Price' and 'OrderPosition.Price#Price' with defining navigations. If a property value changes, it will result in two store changes, which might not be the desired outcome.
我完全理解这个异常,它甚至被记录为一个设计限制:https://learn.microsoft.com/en-us/ef/core/modeling/owned-entities#by-design-restrictions
Instances of owned entity types cannot be shared by multiple owners (this is a well-known scenario for value objects that cannot be implemented using owned entity types).
但是你怎么解决这个问题呢?我是否需要为ItemPrice和OrderPositionPrice创建一个派生类,并相互进行隐式转换?这是可行的,但我认为这不是最好的解决方案。
对于上述EF Core约束,重要的是不要传递相同的值,而是传递一个副本。。
public record Price(decimal Amount, string Currency)
{
public Price Copy() => new(this);
}
// used
var price = new Price(42.0, "USD");
item.Price = price.Copy();
orderPosition.Price = price.Copy();