我有三个表 - 上下文,会话和用户。以下是他们的简化结构。
用户:
UserId(Int,PK)
电子邮件(Varchar(100))
上下文
ContextId(Int,PK)
UserId(来自用户表的Int,FK)
CurrentSessionId(Int,Nullable,FK from Session table)
会话
SessionId(Int,PK)
UserId(来自用户表的Int,FK)
ContextId(来自Context表的Int,FK)
以下是我的代码中删除用户实体的顺序。
1)将Context表的CurrentSessionId更新为null,其中UserId = UserId将被删除。
2)删除与用户对应的所有会话
3)删除与用户对应的所有上下文
4)最后删除用户。
5)调用ObjectContext.SaveChanges()
在调用ObjectContext.SaveChanges()时,我得到以下异常 -
无法确定相关操作的有效排序。由于外键约束,模型要求或存储生成的值,可能存在依赖关系。
我猜EF4很难确定前3个语句的执行顺序。 是否可以告诉EF4首先执行哪些语句以及下一步执行哪些语句?
我可以解决的一种方法是在第一步之后调用SaveChanges(),然后在第四步之后再次调用它。但我很想知道是否还有其他优雅的解决方案。
答案 0 :(得分:4)
基于this MSDN link,不能在EF4中强制执行。我必须在第一步之后两次调用SaveChanges(),然后在第四步之后再调用一次。
答案 1 :(得分:0)
我认为问题在于Session
和Context
之间的循环引用;如果你摆脱Context.CurrentSessionId
,那么你生成的Context
对象仍然会有一个Sessions
属性,但是EF不应该试图协商依赖关系。您可以手动将CurrentSession
属性添加到Context
,如下所示:
public Session CurrentSession
{
get { return this.Sessions.FirstOrDefault(); }
}
此外,如果您将EF模型中的User -> Context
和User -> Session
关系设置为级联删除(甚至更好in the database),那么删除User
只会变成两个行:
objectContext.Users.DeleteObject(user);
objectContext.SaveChanges();