Multiplicity constraint violations with optional-required EF Code First + Fluent relationship?

672 views Asked by At

For some reason I had my made my mind a while back on an EF 6 project that I would try to avoid naming foreign keys. I defined much of the model without testing it incrementally and so I have been running into multiplicity and incomplete Fluent API definition issues:

A relationship from the 'User_InternalAuth' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'User_InternalAuth_Target' must also in the 'Deleted' state.

In one case, here is the code:

nModelBuilder.Entity<User>()
    .HasOptional<InternalAuth>(u => u.InternalAuth)
    .WithRequired(a => a.User)
    .WillCascadeOnDelete(true);

My understanding is that it is saying:

  • The entity User
  • Has an optional property InternalAuth of type InternalAuth
  • On the other end, InternalAuth has a required property User, so that all InternalAuths have Users but Users may or may not have an `InternalAuth.
  • If the User gets deleted, so does his InternalAuth if he has one (does this override an optional behavior of treating optionals like nullables?)

However when I try to delete a User I receive an exception about the multiplicity of some association between InternalAuth and User.

  1. Is it true that if EF understands the multiplicity of a relationship there is a way for it to provide it a unique column name for it so there is a canonical naming convention?

  2. If so, do you ever really need to define foreign keys explicitly by annotating the model or through Fluent API?

  3. If not, is it a worthwhile or advisable thing that I should keep trying to avoid it? (I'm thinking along the lines of migrating the data model, database administration, any EF quirks)

  4. Why does attempting to delete the relationship above violate a multiplicity constraint? What else does it need to know?

1

There are 1 answers

0
tschmit007 On

assuming that

You can configure cascade delete on a relationship by using the WillCascadeOnDelete method. If a foreign key on the dependent entity is not nullable, then Code First sets cascade delete on the relationship. If a foreign key on the dependent entity is nullable, Code First does not set cascade delete on the relationship, and when the principal is deleted the foreign key will be set to null.

My guess is the following : the FK is nullable so the fact to set it to null with the required constraint causes the rise of the exception.

One solution is to put the FK in the PK, that is add, in InternalAuth, the FK to User in the PK. Doing this will mark the entity as deleted when setting a part of his PK to null.