实体框架将仅将相关实体属性设置为“null”如果我第一次得到的财产 [英] Entity Framework will only set related entity property to "null" if I first get the property

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

问题描述

编辑
这似乎发生在任何 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屋!

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