Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework: A referential integrity constraint violation on many to many relationship

Hey I have an application with a bunch of inproc caching and entity framework. When I want to write an update to an entity I reattach the cached copy. I track all things I've attached in the life cycle of the context so I don't try to attach them twice.

I have an error occurring on attach (very rarely in most cases this works fine and is really fast) which says the following:

A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.

I've taken a really careful look at the entity which looks normal. I think this issue is due to the attachment/detachment of a foreign key when fixups runs.

Is there a good way to get any more info on this error or can it occur for reasons other than that the entity was in a state which EF wasnt expecting?

EDIT: DB Diagram (note i'm using codefirst I just used the EDMX tool to make the diagram, I've also chopped a bunch of regular properties off the model for simplicity)

enter image description here

like image 643
Not loved Avatar asked Apr 03 '12 20:04

Not loved


People also ask

What violates the referential integrity constraint?

Referential integrity is violated when the relation to which a foreign key refers no longer exists. For example, if one deletes a donor from the Donor table, without also deleting the corresponding donations from the Donation table, then the DonorID field in the Donation record would refer to a non-existent donor.

What is referential integrity constraints in SQL?

Referential Integrity is a constraint in the database that enforces the relationship between two tables. The Referential Integrity constraint requires that values in a foreign key column must either be present in the primary key that is referenced by the foreign key or they must be null.

What is the use of integrity constraints?

Integrity Constraints are the protocols that a table's data columns must follow. These are used to restrict the types of information that can be entered into a table. This means that the data in the database is accurate and reliable. You may apply integrity Constraints at the column or table level.


2 Answers

The error could occur for the one-to-many relationship between Person and Location you apparently have in your model in addition to the many-to-many relationship. For example the following code would throw the exception:

using (var context = new MyContext()) {     var person = new Person     {         CurrentLocationId = 1,         CurrentLocation = new Location { Id = 2 }     };     context.People.Attach(person); // Exception } 

"The property values that define the referential constraints" are the foreign key property value CurrentLocationId and the primary key value CurrentLocation.Id. If those values are different the exception is thrown. (Having CurrentLocation as null though is allowed.)

In my opinion this exception can only be thrown for foreign key associations because only for this type of association you have properties that define referential constraints at all in your model. It cannot be thrown for independent associations. Since every many-to-many relationship is an independent association (no foreign key property in the model) my guess is that the error is not related to your many-to-many relationship, but to the one-to-many.

like image 53
Slauma Avatar answered Sep 30 '22 01:09

Slauma


I came across a very similar exception:

"A referential integrity constraint violation occurred:  The property value(s) of 'ObjectA.PropertyX' on one end of a relationship  do not match the property value(s) of 'ObjectB.PropertyY' on the other end." 

The reason was this: The client side of the web API sent a PUT request with the entire object including the navigation property (in this example ObjectA (more correctly ObjectB.ObjectA) was a navigation property and was fully supplied by the client). This occurs because the client receives the entire object from the server and bounces it as-is back to the server with minor changes.

On the other hand, the ObjectB.PropertyY had just been changed (this was the reason for the PUT request in the first place).

Since ObjectB.PropertyY was a reference to the same object ObjectA (a foreign key), EF tried to reconcile this and failed with the above exception.

The solution was simple:

ObjectB.ObjectA = null; 

before the SaveChanges() solved this completely.

I hope this helps someone.

like image 37
Erez Lerner Avatar answered Sep 30 '22 01:09

Erez Lerner