我有一个数据库设计问题,我试图也适合Entity Framework。它的复杂性,我继承了它,为时已晚,无法做出重大改变!在做出如何前进的决定之前,我想借鉴其他人的智慧...我原来的帖子要长得多,但我认为业务逻辑细节可能并不重要。
所以简单地说明问题,比如我在同一个数据库中有两个表:
标识, (其他栏目......)
标识, TableId(< ---软键), TableTypeId, (其他栏目......)
现在TableB对表A有一个“软键”,通常可以是外键,但是我所拥有的架构不是,并且相信我它不可能(原因是“假外国”关键点“指向76个不同表中的任何一个,具体取决于TableB的”TableTypeId“列中的内容。)
现在,我们正在使用Entity Framework。显然,两个表之间不能有导航属性。问题是我需要在单个事务中处理这两个表。例如,当我向TableA添加记录时,我还需要向TableB添加一条记录,并使用TableA中为TableB的“TableId”列创建的新Identity值。
使用Navigation属性,我可以在内存中连接两个EntityObjects,然后调用Context.SaveChanges()和EntityFramework在事务中完成所有操作。但是,如果没有导航属性,我必须先插入TableA,获取Identity,然后使用第一个插入的结果插入TableB。这是两笔交易......
我听说Entity Framework允许您在更复杂的情况下处理更多事务,例如定义自己的事务范围和使用其他参数到COntext.SaveChanges()。然而,在我尝试这个之前,我想知道我的问题是否可以在一次交易中解决......
除了架构重新设计之外,我还有哪些选项......
由于
答案 0 :(得分:0)
...哎哟
在EF 4.0中,您可以覆盖保存更改方法,手动启动事务,将TableB模型设置为未更改,保存表A,AcceptAllChanges(),将TableB标记为已更改,然后保存TableB。
对于EF1,您必须手动启动环境事务(使用var scope = new TransactionScope){},然后执行相同的过程。将TableA添加到您的上下文中,如果已添加标记TableB为未更改,则调用SaveChanges(希望仅保存您的TableA对象),调用AcceptAllChanges(),将TableB更新为已更改并添加软键值,再次调用SaveChanges。完成交易。
AcceptAllChanges()或ChangeObjectState()是你的朋友:
在这两种情况下,必须告诉EF忽略TableB,保存TableA,然后在环境事务中再次关注TableB。这是100%可能的(我会做类似的事情)它只需要一些工作。
伪代码:
using (TransactionScope transaction = new TransactionScope())
{
//Set TableB as unchanged so EF ignores it
YourObjectContext.ObjectStateManager.ChangeObjectState(TableBObject,EntityState.Unchanged);
YourObjectContext.SaveChanges();
YourObjectContext.AcceptAllChanges();
TableB.SoftFK = TableA.Fk;
YourObjectContext.ObjectStateManager.ChangeObjectState(TableBObject,EntityState.Modified);
YourObjectContext.SaveChanges();
YourObjectContext.AcceptAllChanges();
Transaction.Complete();
}