首页 文章

正确的方法来检查上下文处理后是否加载了贪婪的实体?

提问于
浏览
2

可能不相关,但我正在使用:

.NET MVC 5.2.3 w / Razor 3.2.3,实体框架6.1.3代码优先,Visual Studio 2015 .

好吧,在我的控制器方法中,我有 - 实质上,但为了简洁而愚蠢:

using( var context = new MyContext() ) {
    var person = context.Persons.Include( x => x.PostalCode ).FirstOrDefault();
    return View(person);
}

现在,最初Zip数据输入属性不是外键...只是用户输入的5位数字符串 . 然而,现在,它本质上是一个外键,以便我们可以获得邮政编码信息 .

public string Zip { get; set; }
[ForeignKey("Zip")]
public virtual PostalCode PostalCode { get; set; }

结构不理想......我知道......

但无论如何,如果用户有我们系统识别的邮政编码,那么一切都很好,一切都在加载 . 但是,如果用户具有未知或无效的邮政编码,例如 00000 ,EF看到非空的外键,这会导致以下问题:

在我的视图文件中(所以在我处理了我的上下文之后),我检查了我们贪婪的实体的属性:

@if( person.PostalCode != null && person.PostalCode.IsInServiceArea ) {
    <div>Service Area HTML</div>
}

不幸的是,由于EF覆盖了我的虚拟 property ,即使没有PostalCode,它也存在 :(

The obvious solutions (please don't answer w/ these):

  • 验证条目上的邮政编码,只允许我们知道的邮政编码并将未知的邮政编码设置为NULL(我喜欢这个,但我没时间重新设计)

  • 在打开上下文时获取IsInServiceArea的值并将其直接放在我的视图模型中,以便在处理上下文之前设置值 . (这实际上是我需要这个答案):

The Question

在实体框架中,Code-First,检查上下文被处理后是否加载了一个贪婪加载的LEFT OUTER JOIN'd实体的正确方法是什么?

根据我发现的答案(例如下面的内容),我认为如果没有上下文打开,这可能是不可能的......但是我想我还是会问:

2 回答

  • 0

    因此,回头看我的评论,你可以完全禁用延迟加载和代理创建 . 只需找到dbcontext类型的构造函数,然后将这两行添加到方法中:

    this.Configuration.LazyLoadingEnabled = false;
    this.Configuration.ProxyCreationEnabled = false;
    

    这样您就可以全局禁用它(无论何时创建上下文,运行ctor,都会应用这些设置) .

    或者,如果您在创建后在上下文对象上设置了这些实例,则可以为一个实例禁用它 .

  • 1

    或者,让您的上下文遍历整个请求,以便在视图上实现延迟加载 .

    Startup.Auth.cs

    public void ConfigureAuth(IAppBuilder app)
    {
        MyContext Create() { return new MyContext(); }
        app.CreatePerOwinContext(Create);
        ...
    }
    

    MyController.cs

    var context = HttpContext.GetOwinContext().Get<MyContext>();
    var person = context.Persons.Include( x => x.PostalCode ).FirstOrDefault();
    return View(person);
    

相关问题