Vac*_*ano 17 c# entity-framework circular-dependency entity-framework-4
说我有这个表结构:
Client
-----------
ClientId int not null (identity)
CurrentDemographicId int null (FK to ClientDemographic)
OtherClientFields varchar(100) null
ClientDemographic
------------------
ClientDemographicId int not null (identity)
ClientId int not null (FK to Client)
OtherClientDemographicFields varchar(100) null
Run Code Online (Sandbox Code Playgroud)
我们的想法是Client(在EF中)将具有ClientDemographics列表和CurrentDemographic属性.
问题是当我设置对象结构并尝试保存它时,我收到此错误:
无法确定相关操作的有效排序.由于外键约束,模型要求或存储生成的值,可能存在依赖关系
这个错误是有道理的.我在表格设置中有一个循环引用.它不知道首先插入哪个实体(因为它同时需要来自两个表的Id).
所以,我一起破解了一个看起来像这样的解决方案:
// Save off the unchanged ClientDemograpic
ClientDemographic originalClientDemographic = client.CurrentClientDemographic;
// Merge the contract into the client object
Mapper.Map(contract, client);
// If this is a new client then add as new to the list.
if (client.ClientId == 0)
{
dataAccess.Add(client);
}
// Restore the original ClientDemographic so that EF will not choke
// on the circular reference.
ClientDemographic newClientDemographic = null;
if (client.CurrentClientDemographic != originalClientDemographic)
{
newCurrentClientDemographic = client.CurrentClientDemographic;
client.CurrentClientDemographic = originalClientDemographic;
}
// save our changes to the db.
dataAccess.SaveChanges();
// Restore updates to ClientDemographics and save (if needed)
if (newClientDemographic != null)
{
client.CurrentClientDemographic = newCurrentClientDemographic;
dataAccess.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)
但是将参考值更改回以前的值,保存,然后再次设置,以便我可以再次保存感觉就像一个黑客.
有没有更简洁的方法来处理EF中的循环引用?
Ste*_*kes 15
我会说答案是:"不是真的".处理循环引用的唯一简洁方法是再次查看设计并将其删除.
在这种情况下 - 从Domain Driven Design的角度来看它 - 我会说这Client
是你的聚合的根,它ClientDemographic
是一个值对象; ClientDemographics
由他们的"其他ClientDemographic字段"的值定义.因此,您可以删除ClientId
从ClientDemographic
,并且防止了问题,而不是治愈.
也就是说,如果你已经确定了这个结构,那么不幸的是我认为在EF中没有一种巧妙的处理方法,没有.
编辑:为了给Client
多ClientDemographics
还有一个CurrentClientDemographic
属性,你可以走另外一条道路; CurrentClientDemographicId
从中删除Client
,并添加IsCurrent
二进制字段ClientDemographic
.然后,EF会为您提供一个ClientDemographics
集合属性,您可以在一个新的分部类中添加以下内容:
public partial class Client
{
public ClientDemographic CurrentDemogaphic
{
get { return this.ClientDemographics.First(cd => cd.IsPrimary); }
}
}
Run Code Online (Sandbox Code Playgroud)