摘要
在Entity Framework Core [Code-First]中,是否可以通过该导航属性的私有(甚至公共)支持字段来映射该导航属性?本质上不是将其映射为:
modelBuilder.Entity<MyEntity>().HasMany(e => e.NavProperty)...
我们可以将其映射为(本质上,为了简洁起见,忽略反射或硬编码的字符串):
modelBuilder.Entity<MyEntity>().HasMany(e => e.NavProperty._Data)...
将NavProperty
视为导航属性并处理关系(即外键)吗?
我似乎无法弄清楚实现这种结果所需的Fluent API映射配置。我似乎记得在EF 6中这样做过,但可悲的是我再也没有该项目的源代码了。
详细信息
更全面的示例(C#、. NET Standard 2.2,Entity Framework Core 2.2 [Code-First]):
public class Customer
{
public int CustomerID { get; set; }
public string Name { get; set; }
// ...
public OrderCollection Orders { get; set; }
public Customer()
{
}
}
public class Order
{
public int OrderID { get; set; }
public string OrderNo { get; set; }
public bool Shipped { get; set; }
// ...
public Customer Customer { get; set; }
public Order()
{
}
}
public class OrderCollection : IReadOnlyCollection<Order>
{
private HashSet<Order> orders = new HashSet<Order>();
public OrderCollection()
{
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.orders.GetEnumerator();
}
public void Add(Order order)
{
this.orders.Add(order);
// ... Other logic here
}
public bool Contains(Order order)
{
// ... Other logic here
return this.orders.Contains(order);
}
}
// The DbContext Class...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//... Other models setup / plumbing completed
// How do we map the sub property / field??
modelBuilder.Entity<Customer>().HasMany(customer => customer.Orders).WithOne(order => order.Customer);
}
该示例有些人为设计,但相当简单,只是为了快速入门:
本质上,OrderCollection
是专用orders
HashSet字段的包装,通过该字段,我们可以封装来自突变的真实数据,而通过所需的接口公开我们想要的行为。它还允许在最合适的时间处理域事件和/或其他问题,而调用者/所有者无需了解详细信息或不必在整个域模型中重复逻辑(即,帐单也将具有订单集合,质量也将如此)控制等)。它还可以防止依赖关系和横切关注点泄漏到主域模型中。
头脑风暴
我解决问题的一些想法包括:
1)让OrderCollection
继承自HashSet<T>
,ReadOnlyCollection<T>
之类的东西,然后重写我不想公开的方法。充其量看来,这似乎确实很hacky和脆弱(例如,我们通过怪异的伏都教徒魔术违反了“偏爱组成而非继承”的做法)。
2)只需转储“集合”的想法,并将项目的后备字段和所有逻辑放入违反DRY的实体模型中(其他模型将为{{1}使用相同类型的API }属性和SRP,因为现在我的Orders
对象知道如何(例如如何实现的详细信息)向自身添加Customer
。这是糟糕的设计。
3)通过自定义SQL /存储库/获取器和设置器/等手动处理导航属性?似乎EF应该在后台进行所有这些操作,而这可能是“重新发明轮子”。
我确实尝试过使用Order
,但似乎它们是用于处理来回处理的数据库类型和.NET CLR类型的细微/深奥的问题的。也许这是最好的解决方案,但是它需要特定类型的ValueConverter构造才能正常工作?
任何帮助或见识都受到赞赏!谢谢!