C# 域模型vs实体FW:在持久性模型中拆分是有用的吗?
在DDD方法中,我有一个具有丰富行为的域模型(DM)。假设我有一个根实体,名为C# 域模型vs实体FW:在持久性模型中拆分是有用的吗?,c#,entity-framework,domain-driven-design,C#,Entity Framework,Domain Driven Design,在DDD方法中,我有一个具有丰富行为的域模型(DM)。假设我有一个根实体,名为Order和relativeLineOrder。LineOrder的公开集合需要是IReadOnlyCollection,因为没有人可以任意更改集合。代码: public class Order : AggregateRoot { // fields private List<LineOrder> lineOrder; // ctors private Order() {
Order
和relativeLineOrder
。LineOrder
的公开集合需要是IReadOnlyCollection
,因为没有人可以任意更改集合。代码:
public class Order : AggregateRoot {
// fields
private List<LineOrder> lineOrder;
// ctors
private Order() {
this.lineOrder = new List<LineOrder>();
// other initializations
}
// properties
public IReadOnlyCollection<LineOrder> LineOrder {
get
{
return lineOrder.AsReadOnly();
}
}
// behaviours
}
公共类顺序:AggregateRoot{
//田地
私有列表行顺序;
//演员
私人命令(){
this.lineOrder=新列表();
//其他初始化
}
//性质
公共IReadOnlyCollection行顺序{
得到
{
return lineOrder.AsReadOnly();
}
}
//行为
}
到目前为止,一切顺利。但是,当我想要持久化这个领域时,我有一些由实体框架施加的技术限制(即使我有一个值对象、一个无参数构造函数等等,也需要一个键),这与DDD方法并不完全匹配。
我的另一个限制是:
public class OrderConfiguration : EntityTypeConfiguration<Order>
{
public OrderConfiguration()
{
ToTable("Order");
HasMany<LineOrder>(m => m.LineOrder); // Exception: Cannot convert from IReadOnlyCollection to ICollection
}
}
公共类OrderConfiguration:EntityTypeConfiguration
{
公共订单配置()
{
可转帐(“订单”);
HasMany(m=>m.LineOrder);//异常:无法从IReadOnlyCollection转换为ICollection
}
}
我无法将IReadOnlyCollection
转换为ICollection
(顺便说一句,如果LineOrder
是ICollection
一切正常!)
出于我上面所表达的原因:在这种情况下是否可以创建一个持久性模型(有缺点:映射DM/PM和viceversa)
还有别的选择吗?最重要的是:是否有适合DDD方法的替代方案?您是否尝试将
LineOrder
集合声明为受保护的?通过这种方式,EF可以访问,但消费者不能访问
// properties
protected ICollection<LineOrder> LineOrder { get; set; }
//属性
受保护的ICollection LineOrder{get;set;}
然后,您可以通过以下方式以只读方式向最终用户公开此集合:
public IReadOnlyCollection<LineOrder> ReadOnlyLineOrder
{
get
{
return LineOrder.ToList().AsReadOnly();
}
}
public-IReadOnlyCollection-ReadOnlyLineOrder
{
得到
{
return LineOrder.ToList().AsReadOnly();
}
}
IMO这是一条评论,不是答案。是的,它可以工作,但有几个副作用:i)我不想向消费者隐藏LineOrder
,而是想隐藏LineOrder
ii)如果调用Add
,则使用ICollection
而不是IReadOnlyCollection
将导致运行时错误(其中,IReadOnlyCollection
将产生编译时错误,这样更好)抱歉,我没有说得更完整。我将编辑答案以提高清晰度。域和配置位于两个不同的类中,并且没有继承关系:\n使用这种方法,您的EF映射/配置不需要更改。对我来说,使用IReadOnlyCollection有点奇怪。我记得IReadOnlyCollection没有sn不保存编辑内部元素的功能。因此我可以执行readOnlyCollection.First().Amount=100之类的操作。因此,它也不是很好。您不想使用IList而不是IReadOnlyCollection,只复制lineOrder吗?从概念上讲,还有两种解决方案:1)返回包含lineOrder项的列表的完整副本,2)删除一些访问器并使用另一个具有自定义LineOrder表示的公共方法