Edit
This seems to occur for any Entity property that references another entity in one direction. In other words, for the below example, the fact that Bar
overrides Equality appears to be irrelevant.
Suppose I have the following classes:
public class Foo
{
public int? Id { get; set; }
public virtual Bar { get; set; }
}
public class Bar : IEquatable<Bar>
{
public int Id { get; set; }
public override bool Equals(object obj)
{
var other = obj as Bar;
return Equals(other);
}
public bool Equals(Bar other)
{
if (object.Equals(other, null))
return false;
return this.Id == other.Id;
}
public static bool operator ==(Bar left, Bar right)
{
return object.Equals(left, right);
}
public static bool operator !=(Bar left, Bar right)
{
return !object.Equals(left, right);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
}
Note that here, "Bar" intentionally has "Id" equality, because it more or less represents a lookup table - so any two object references with the same Id should always be considered the same.
Here's the weird part, this all works fine when I set Foo.Bar
to another Bar
instance - everything updates as expected.
However, if foo
has an existing Bar
when it is retrieved from the DbContext
and I do:
foo.Bar = null
then the property doesn't actually change!
If I do:
var throwAway = foo.Bar;
foo.Bar = null;
Then the property will actually set and save as null.
Since the Foo.Bar
property is simply a virtual, auto-implemented property, I can only conclude that this has something to do with lazy-loading and Entity Framework proxies - but why this particular scenario causes a problem, I have no idea.
Why does Entity Framework behave this way, and how can I get it to actually set null
reliably?