当实体框架为空时,它会尝试再次延迟加载对象

时间:2016-02-25 03:27:59

标签: c# entity-framework

我对实体框架处理null对象的方式有疑问。 下面的例子是一个简单的1到0..1的关系。如果人员不存在配置文件,则Person对象下的配置文件对象为空。

但EF正在尝试再次进行延迟加载。因此, ObjectDisposedException 是throw。

public void Test()
{
    Person person = null;

    using (var ctx = new MainContext())
    {
        person = ctx.Persons
            .Include(c => c.Profile);
            .FirstOrDefault(p => p.Name == "Ben");
    }

    // ObjectDisposedException is throw here if Profile doesn't exist
    var profile = person.Profile;
}

似乎EF无法区分“不存在”和“尚未获取”。我现在拥有的最佳解决方案是禁用延迟加载。

Configuration.LazyLoadingEnabled = false;

但是这会隐藏我想要看到的所有ObjectDisposedException,因为有时我可能会忘记包含Include,现在它们都变为null。

处理此事的任何更好的想法?

3 个答案:

答案 0 :(得分:0)

执行左外连接,这将返回所有人,无论他们是否有配置文件。

var query = (from p in ctx.Persons
                join pr in ctx.Profiles on p equals pr.PersonId into gj
                from subpr in gj.DefaultIfEmpty()
                where p.Name == "Ben"
                select p).FirstOrDefault();

More about this

答案 1 :(得分:0)

如果只处理null对象,可以在类构造函数中初始化对象,如下所示:

public Person
{
    this.Profile = new Profile();
}

答案 2 :(得分:0)

它抛出异常的原因是因为延迟加载仅在您需要它时发生而不是在您执行包含时发生。

当您告诉您的代码在您使用之外“需要”配置文件时,EF没有更多上下文来获取数据并且您收到错误。

看看herehere

如果您这样做,您的代码应该有效:

public void Test()
{
    Person person = null;

    using (var ctx = new MainContext())
    {
        person = ctx.Persons
            .Include(c => c.Profile);
            .FirstOrDefault(p => p.Name == "Ben");
            // code inside the using
            var profile = person.Profile;
        }
    }
}

我希望它有所帮助。 : - )