c# - 实体框架无法在实体构造函数中绑定值对象
问题描述
我创建了一个实体,它在其构造函数中将值对象作为参数,但是当我将实体添加到 db 上下文时,它会引发以下异常。
InvalidOperationException:找不到适合实体类型 >'BasketItem' 的构造函数。以下构造函数的参数无法>绑定到实体类型的属性:无法在>'BasketItem(Guid id,Guid productId,DateTimeOffset addedAt,Money price)'中绑定'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值对象有几个缺点,这是因为 EF Core 拥有的实体类型仍被视为实体,并且返回拥有的实体类型的属性被视为导航属性。
在这种特殊情况下,问题是由上述最后一个事情以及以下实体类型构造函数限制引起的
需要注意的一些事项:
- EF Core 无法使用构造函数设置导航属性(例如上面的博客或帖子)。
解决方法/解决方案是提供 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
为拥有的实体类型。
推荐阅读
- c# - 如何将产量应用于递归函数
- javascript - P5 用数学旋转一个形状
- java - 如何使方法返回类型为 Callable
- unity3d - 是否可以使用 ARcore depth api 创建 3d 扫描仪。可以从收集的点云构建 3d 模型吗?
- hsqldb - 哪种 HSQLDB 数据类型最适合 5000 个字符串:NTEXT、CLOB 或其他。?
- entity-framework-core - 如何在 .Net EF Core 中将本地化实现为 JSON 对象?
- javascript - 我想实现反应水平无限滚动。没有得到适当的解决方案。有没有人在 react 或 javasrcipt 中构建过这个
- javascript - 从函数返回返回未定义
- flutter - Flutter mapbox折线图
- python - Tensorflow 错误“TypeError:传递给 'Pack' Op 的 'values' 的列表中的张量具有不完全匹配的类型 [int32, int64, int32, int32, int32]。”