EF6 Code First:具有多种关系的实体

时间:2013-11-27 02:30:32

标签: c# .net vb.net entity-framework entity-framework-6

我正在使用EF代码创建一个新的数据库,它包含以下类:

Address, Contact, Account, Customer (a sub-class of Account), and SalesOrder. 

Address类是目前给我带来问题的类,它可以没有外键,因为它可以链接到其他五个类中的任何一个(还有更多),而其他每个类都可以有一个或更多指向它的导航属性。

导航属性应如下所示:

Contact.AddressId?
Contact.Address

Account.AddressId?
Account.Address

Customer.DeliveryAddresses

SalesOrder.InvoiceAddressId
SalesOrder.InvoiceAddress

SalesOrder.DeliveryAddressId?
SalesOrder.DeliveryAddress

这些类应该可以共享相同的地址记录,例如帐户具有地址,也可以链接到SalesOrder,链接到客户的不同地址可以链接到另一个SalesOrder。链接到帐户和客户的所有地址都应该是唯一的,但其他类应该能够共享这些地址的链接。

我已经尝试使用我能想到的所有可能的流畅配置来设置它,我的DbContext具有DbSet属性而没有(最终我认为它不应该拥有它自己的DbSet属性,因为地址应该只是可以从各种根对象访问,但如果这是让它工作的唯一方法,我很乐意自己管理插入/删除。)

我尝试使所有导航属性都可以为空(理想情况下SalesOrder.InvoiceAddressId不应该为空),并且还必须在某一时刻删除Customer.DeliveryAddresses多对多映射,因为这会使问题混乱。

我得到各种错误取决于我如何设置,或者由于不可空字段导致多重性冲突,或者当我没有DbSet属性时我会尝试让EF处理插入和删除时出现Cascade on Delete错误。 / p>

当我确实设置了DbSet属性时,我也会得到不需要的空行。 e.g:

add three Address records to the DbSet (Address(1), Address(2), Address(3),
add two Accounts to the DbSet (Account(1) & Account(2)),
add multiple SalesOrders,
set Account(1).AddressId = 1
set Account(2).AddressId = 2, 
set SalesOrder(n).InvoiceAddressId = 1,
set SalesOrder(n).DeliveryAddressId = 3

这将正确创建地址记录,但只有在使用各种Id外键属性而不是导航属性时才会正确设置相关键,即使使用了Id属性外键所有外观也是如此正确但每个SalesOrder的孤立记录(如果使用两个导航属性,则每个订单两个),最终在我的地址表中,其所有字段栏ID设置为NULL。

我唯一能想到的就是我没有尝试过将创建多个Address子类并将每个子类与它的相关类(例如SalesOrderDeliveryAddress)一起使用,但这似乎并不理想。除非必须,否则我宁愿不这样做。

我正在寻找可以在EF中设置的内容,还是有其他方法可以实现呢?

谢谢, 大卫

1 个答案:

答案 0 :(得分:1)

有几个问题令人困惑。首先,我会关闭删除时的默认级联,以摆脱多个级联路径,然后再回过头来。

然后阅读有关在此处添加断开连接的树,外键和导航属性的信息:http://msdn.microsoft.com/en-us/magazine/dn166926.aspx

然后,我会按照您希望的方式设置实体,并重新发布更具体的问题。 (你已经尝试了很多东西,所以很难弄清楚这里会发生什么)

一旦你进行了添加和更新工作,你就可以回来找出可以进行级联删除的地方,以及需要手动删除的地方