我创建了一个实体,该实体在其构造函数中将值对象作为参数,但是当我将该实体添加到db上下文时,它将引发以下异常。
InvalidOperationException:找不到适用于实体类型>'BasketItem'的合适的构造函数。以下构造函数具有无法绑定到实体类型的属性的参数:无法在'BasketItem(Guid id,Guid productId,DateTimeOffset addAt,Money price)'中绑定'price'。
我在类型配置中尝试过builder.OwnsOne(x => x.Price);
。请记住,我正在使用内存存储提供程序。
BasketItem.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;
}
}
Money.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 };
}
}
答案 0 :(得分:2)
使用EF Core owned entity types来实现DDD 值对象存在一些缺点,这是由于EF Core拥有的实体类型仍被视为实体和属性返回的拥有实体类型被视为导航属性。
在这种情况下,此问题是由上述最后一个问题以及以下Entity Type Constructors局限性引起的
一些注意事项:
- EF Core无法使用构造函数设置导航属性(例如,上面的Blog或Posts)。
解决方法/解决方案是提供供EF使用的特殊私有构造函数:
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
映射为拥有的实体类型。
答案 1 :(得分:1)
不确定那是否仍然有用,今天我在EF遇到了类似的问题。
真正帮助我的是在类中添加了一个空的构造函数**:
public MyClass()
{}
此后,一切都按预期进行,数据库已成功更新。