Entity Framework: avoid multiple saves for circular references

I am getting this exception when calling SaveChanges on the EF ObjectContext:

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

      

I think the problem is that I have a circular dependency on my DB model.

i.e.

Table Users

  • Id
  • ProfilePictureId

Tabular photos

  • Id
  • UserId

I create a new user and set the image

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

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

_db.SaveChanges();

      

But this rules out an exception.

If I add an extra call to SaveChanges () after I set the User It image works just fine, I just want to avoid this double shutdown in the DB.

Any ideas on how to achieve this?

Thank!

0


source to share


2 answers


There is no way to avoid being called SaveChanges

twice with your database design. You cannot insert a user with a dependency on a picture that has not yet been inserted (FK will throw an exception), and at the same time you cannot insert an image with a user dependency that has not yet been inserted (again FK will throw an exception). This is not an EF feature that is a feature of the DB itself.

Also, you don't need to avoid multiple calls SaveChanges

due to multiple calls. EF does not have batch processing of commands, so every insert, update, or delete has its own route to the database anyway.

If you want to call one SaveChanges, you must change your database like this:

Table Users



  • Id (PK, IDENTITY)

Tabular photos

  • Id (PK, FK for users. No identifier IDENTITY)

This is a native one-to-one relationship where the user is the primary and the image is dependent.

+2


source


I would say that this is enough to do the job once (or set a user or an image), that is:

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

user.ProfilePicture = picture;

_db.SaveChanges();

      

You create new objects on the first two lines and you link them with user.ProfilePicture = picture

. EF has to handle the rest.
You don't need to establish a relationship on both sides.



Edit: How about this?

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

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


_db.SaveChanges();

      

0


source







All Articles