简体   繁体   English

实体框架:避免循环引用的多次保存

[英]Entity Framework: Avoid multiple saves for circular references

I'm getting this exception when calling SaveChanges on my EF ObjectContext: 我在EF ObjectContext上调用SaveChanges时遇到此异常:

Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints

I think the problem is because I have a circular dependency on my DB model. 我认为问题是因为我对我的数据库模型有循环依赖。

ie

Table Users 表用户

  • Id ID
  • ProfilePictureId ProfilePictureId

Table Pictures 表图片

  • Id ID
  • UserId 用户身份

I'm creating a new user and setting the picture 我正在创建一个新用户并设置图片

var user = _db.Users.CreateObject();
var picture = _db.Pictures.CreateObject();

picture.User = user;
user.ProfilePicture = picture;

_db.SaveChanges();

But that throws the exception. 但这引发了例外。

If I add an extra call to SaveChanges() after I set the picture's User It works just fine, I just want to avoid that double trip to the DB. 如果我在设置图片的用户之后添加一个额外的调用SaveChanges()它工作得很好,我只想避免数据库的双重行程。

Any ideas of how to achieve this? 有关如何实现这一目标的任何想法?

Thanks! 谢谢!

There is no way to avoid calling SaveChanges twice with your database design. 没有办法避免使用数据库设计调用SaveChanges两次。 You can't insert user with dependency to picture which is not inserted yet (FK will throw exception) and in the same time you can't insert picture with dependency to user which is not inserted yet (again FK will throw exception). 你不能插入依赖于尚未插入的图片的用户(FK将抛出异常),同时你不能插入依赖于尚未插入的用户的图片(再次FK将抛出异常)。 That is not feature of EF that is feature of DB itself. 这不是作为DB本身特征的EF的特征。

You also don't need to avoid multiple SaveChanges calls because of multiple roundtrips. 由于多次往返,您也不需要避免多次SaveChanges调用。 EF doesn't have command batching so each insert, update or delete has its own roundtrip to database anyway. EF没有命令批处理,因此每次插入,更新或删除都有自己的数据库往返。

If you want to call single SaveChanges you must change your database as follows: 如果要调用单个SaveChanges,则必须按如下方式更改数据库:

Table Users 表用户

  • Id (PK, IDENTITY) Id(PK,IDENTITY)

Table Pictures 表图片

  • Id (PK, FK to Users.Id, No IDENTITY) Id(PK,FK到Users.Id,No IDENTITY)

This is native one-to-one relation where User is principal and Picture is dependent. 这是本机一对一关系,其中User是Principal,Picture是依赖的。

I would say that it's enough to make the assignment once (either setting user or picture) ie: 我会说这一次就足够了(设置用户或图片),即:

var user = _db.Users.CreateObject();
var picture = _db.Pictures.CreateObject();

user.ProfilePicture = picture;

_db.SaveChanges();

You are creating new entities at first two lines, and you 'link' them by user.ProfilePicture = picture . 您将在前两行创建新实体,并按user.ProfilePicture = picture “链接”它们。 EF should handle the rest. EF应该处理剩下的事情。
You don't need to setup relation from both sides. 您无需从双方设置关系。

Edit: What about this? 编辑:这个怎么样?

var user = _db.Users.CreateObject();
var picture = _db.Pictures.CreateObject();

picture.user = user;
user.ProfilePictureId = picture.Id;


_db.SaveChanges();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM