Why EF not updating FK column when entity state is not Added?

84 views Asked by At

I have such entity:

 public class Entity1
    {
        public short Id { get; set; }
        public int Entity2Id { get; set; }
        public virtual Entity2 Entity2 { get; set; }
    }

And have such one to Many relationship:

  this.HasRequired(m => m.Entity2)
            .WithMany()
            .HasForeignKey(m => m.Entity2Id)
            .WillCascadeOnDelete(false);

And here is the thinkg which I cannot understand:

For example, evertyhting works fine if I have changed the entity state to Added firstly:

context.Entry(entity1).State = System.Data.EntityState.Added;
entity1.Entity2.Id = 541;

 // Since this line `entity1.Entity2Id` value is 0.
 context.Entry(entity1.Entity2).State = System.Data.EntityState.Unchanged;
 // But now everything is fine, because `entity1.Entity2Id` value is 541 also.

 context.Entry(entity1).State = System.Data.EntityState.Unchanged;

But, I don't want to change state to Added, when I am removing the first line, this exception occured:

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.

Beacuse, entit1.Entity2Id != entity1.Entity2.Id.

And, I don't want manually to change the value.

How, I can make it work without changing the state to Added?

Update:

I have investigated this problem more. From this So question:

This is called property fixup, and used to be done automatically by the generated proxies. However, with DbContext this is no longer the case. According to this Connect issue, this is by design.

Hello, The DbContext template actually doesn't generate classes that will be used as change tracking proxies - just lazy loading proxies (which don't do fix-up). We made this decision because change tracking proxies are complex and have a lot of nuances that can be very confusing to developers. If you want fix-up to occur before SaveChanges you can call myContext.ChangeTracker.DetectChanges. ~EF Team

An alternative is to call DbContext.Entry(entity), which will sync up the entity. This is described in this article: Relationships and Navigation Properties under "Synchronizing the changes between the FKs and Navigation properties"

0

There are 0 answers