实体框架只会将相关实体属性设置为“null".如果我先拿到房产 [英] Entity Framework will only set related entity property to "null" if I first get the property

查看:16
本文介绍了实体框架只会将相关实体属性设置为“null".如果我先拿到房产的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑这似乎发生在 any 在一个方向上引用另一个实体的实体属性上.换句话说,对于下面的示例,Bar 覆盖 Equality 的事实似乎无关紧要.

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 设置为另一个 Bar 实例时,一切正常 - 一切都按预期更新.

Here's the weird part, this all works fine when I set Foo.Bar to another Bar instance - everything updates as expected.

但是,如果 foo 在从 DbContext 中检索到现有的 Bar 时,我会这样做:

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?

推荐答案

作为一种解决方法,我发现缓解此问题的最简单方法是让 setter 在设置支持字段为空,例如

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆