实体框架将仅将相关实体属性设置为“null”如果我第一次得到的财产 [英] Entity Framework will only set related entity property to "null" if I first get the property
问题描述
编辑
这似乎发生在任何 Entity属性,引用另一个实体在一个方向。换句话说,对于下面的例子, Bar
覆盖平等似乎是无关紧要的。
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.
假设我有以下类:
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();
}
}
请注意,在这里,Bar有意地具有Id 等于,因为它或多或少代表查找表 - 所以任何两个具有相同ID的对象引用应始终被视为相同。
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.
这是奇怪的部分,这个当我将 Foo.Bar
设置为另一个栏
实例时,所有工作正常 - 所有更新如预期。
Here's the weird part, this all works fine when I set Foo.Bar
to another Bar
instance - everything updates as expected.
但是,如果 foo
在从...中检索到 Bar
DbContext
,我做:
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!
如果我这样做:
var throwAway = foo.Bar;
foo.Bar = null;
然后属性将实际设置并保存为null。
Then the property will actually set and save as null.
由于 Foo.Bar
属性只是一个虚拟的自动实现的属性,我只能得出结论,这与懒加载和实体有关框架代理 - 但是为什么这个特定的场景会导致一个问题,我不知道。
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.
为什么Entity Framework以这种方式行事,如何让它实际设置 null
可靠?
Why does Entity Framework behave this way, and how can I get it to actually set null
reliably?
推荐答案
作为解决方法,我最简单的方法发现减轻这个问题是让设置者将之前的getter 设置为null,例如
As a workaround, the easiest way I've found to mitigate this issue is to have the setter call the getter before setting the backing field to null, e.g.
public class Foo
{
public int? Id { get; set; }
private Bar _bar;
public virtual Bar
{
get { return _bar; }
set
{
var entityFrameworkHack = this.Bar; //ensure the proxy has loaded
_bar = value;
}
}
}
这样,无论其他代码是否实际加载了该属性,都是以可能不必要的实体加载为代价的。
This way, the property works regardless of whether other code has actually loaded the property yet, at the cost of a potentially unneeded entity load.
这篇关于实体框架将仅将相关实体属性设置为“null”如果我第一次得到的财产的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!