我创建了一个实体,它在其构造函数中将值对象作为参数,但是当我将实体添加到 db 上下文时,它会引发以下异常。
InvalidOperationException: No suitable constructor found for entity type >'BasketItem'. The following constructors had parameters that could not be >bound to properties of the entity type: cannot bind 'price' in >'BasketItem(Guid id, Guid productId, DateTimeOffset addedAt, Money price)'.
我试过
builder.OwnsOne(x => x.Price);
在类型配置中。请记住,我正在使用内存存储提供程序。篮子元素.cs
public sealed class BasketItem : Entity
{
public Guid ProductId { get; private set; }
public DateTimeOffset AddedAt { get; private set; }
public Money Price { get; private set; }
public BasketItem(Guid id, Guid productId, DateTimeOffset addedAt, Money price) : base(id)
{
ProductId = productId;
AddedAt = addedAt;
Price = price;
}
}
钱.cs
public sealed class Money : ValueObject
{
public decimal Value { get; private set; }
public string CurrencyCode { get; private set; }
public Money(decimal value, string currencyCode)
{
Value = value;
CurrencyCode = currencyCode;
}
protected override IEnumerable<object> GetAtomicValues()
{
return new object[] { Value, CurrencyCode };
}
}
最佳答案
使用 EF Core 实现 DDD 值对象 owned entity types有几个缺点,原因是 EF Core 拥有的实体类型仍被视为 实体 ,并且返回拥有的实体类型的属性被视为 导航属性 .
在这种特殊情况下,问题是由前面提到的最后一个事情以及以下 Entity Type Constructors 引起的。局限性
Some things to note:
- EF Core cannot set navigation properties (such as Blog or Posts above) using a constructor.
解决方法/解决方案是提供 EF 使用的特殊私有(private)构造函数:
public BasketItem(Guid id, Guid productId, DateTimeOffset addedAt, Money price) : this(id, productId, addedAt)
{
Price = price;
}
/// <summary>
/// EF constructor
/// </summary>
private BasketItem(Guid id, Guid productId, DateTimeOffset addedAt) : base(id)
{
ProductId = productId;
AddedAt = addedAt;
}
当然使用
[Owned]
属性或 OwnsOne
流畅的 API 映射 Money
作为拥有的实体类型。
关于c# - Entity Framework 无法在实体构造函数中绑定(bind)值对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55749717/