【问题标题】:Disable lazy loading by default in Entity Framework 4在 Entity Framework 4 中默认禁用延迟加载
【发布时间】:2011-02-27 08:59:59
【问题描述】:

似乎在 EF4 中默认启用延迟加载。至少,在我的项目中,我可以看到

dataContext.ContextOptions.LazyLoadingEnabled

默认为真。我不想延迟加载,也不想写:

dataContext.ContextOptions.LazyLoadingEnabled = false;

每次我得到一个新的上下文。那么有没有办法在整个项目中默认关闭它?

【问题讨论】:

    标签: entity-framework lazy-loading entity-framework-4


    【解决方案1】:

    以下答案是指 Database-FirstModel-First 工作流程(实体框架(版本 Code-First 工作流程(自 EF 版本 >= 4.1 起可用),请继续向 ssmith 的 answer 发送此问题以获得正确的解决方案。


    edmx 文件在<ConceptualModel><EntityContainer> 定义中有一个延迟加载属性,您可以将延迟加载一般设置为false:

    <EntityContainer Name="MyEntitiesContext" annotation:LazyLoadingEnabled="false">
    

    这会在 ObjectContext 构造函数中创建以下设置:

    public MyEntitiesContext() : base("name=MyEntitiesContext", "MyEntitiesContext")
    {
        this.ContextOptions.LazyLoadingEnabled = false;
        OnContextCreated();
    }
    

    我的示例并不意味着应该手动编辑生成的ObjectContext(或较新的 EF 版本中的DbContext)(正如 ctorx 指出的那样,这将被数据库中的每个模型更新覆盖)但是EDMX 文件的edmx:ConceptualModels 部分中的EntityContainer 元素应通过添加annotation:LazyLoadingEnabled="false" 属性来编辑 - 在 XML 编辑器中手动或在此选项可用的设计器界面的属性页面上,对- 单击 EDMX,然后单击属性。

    EDMX 文件的这种修改将自动生成上下文类,并在构造函数中禁用延迟加载选项,如上所示。从数据库更新模型时,EDMX 文件修改本身不会被覆盖。

    【讨论】:

    • 这需要您修改生成的代码,如果您修改模型,这些代码将被覆盖。考虑放置一个 ObjectContextFactory,并在工厂中进行更改。这样,您仍然只需要设置一次选项,并且不会更改自动生成的代码。
    • @ctorx - AFAICT 比工厂更简单的选项是仅实现部分 OnContextCreated 以关闭延迟加载?还是我错过了什么?
    • 工厂还可以根据需要或通过依赖注入有条件地允许显式提供连接字符串,因此在我看来,添加的抽象证明了工厂的合理性,尽管从技术上讲,这不是必需的。跨度>
    • @ctorx:两年多之后,在我什至支持你的评论之后,因为我认为你的批评者是绝对正确的,现在我再次理解了我自己的答案,实际上不需要修改生成的代码全部 :) 请参阅我答案底部的编辑部分。
    • 我再次将您的答案标记为已接受,以试图消除任何混乱(或者它可能只会造成更多混乱!)。
    【解决方案2】:

    您也可以从设计师那里完成。只需打开 .edmx 文件,右键单击模型上的任意位置并选择属性。然后将LazyLoadingEnabled 设置为false。

    【讨论】:

      【解决方案3】:

      我写了一个显示how the new Lazy Loading features work with EF Code First 的快速示例。在 Code First 模型中实现您想要的只需在 DbContext 的构造函数中添加一行,如下所示:

      public BlogContext()
      {
          this.Configuration.LazyLoadingEnabled = false;
      }
      

      【讨论】:

      • 这并不重要,但: base()this. 在这段代码中都是多余的。
      • 就功能而言,是的,就可读性而言,我认为有时包含this 很有用。我同意base(),但我想不出添加它的理由。
      • 是的,不知道为什么 base() 曾经在其中。已删除。
      • base() 用于指定要使用的连接字符串,对吧?仅当您不指定一个时,它不是多余的吗?
      【解决方案4】:

      如果您可能使用的是 EF4 Code First,是吗?因此,在您的上下文的初始化中,有 'OnModelCreated' 的覆盖。

      在这个方法中,我只是简单地调用并设置了属性,一切都解决了。

      protected override void OnModelCreating(DbModelBuilder modelBuilder) {
           base.Configuration.LazyLoadingEnabled = false;
      }
      

      我的模型现在更可口了。延迟加载很棒......但不是当你不想要它时。当你开始有循环引用时,这简直是荒谬的。

      【讨论】:

      • 这不起作用,因为它只会对构建模型的上下文实例(通常是应用程序启动后第一个使用的实例)禁用延迟加载。对于所有以后的上下文实例,OnModelCreating 不会被调用,LazyLoadingEnabled 将具有默认值 - 即 true
      • @Slauma - 我今天遇到了完全相同的问题,并且我已经编辑了这个答案(因为它是被接受的)以将其更改为将其设置在 ctor 中。如果我有权将已接受的答案从这个更改为您的,我会这样做。 :)
      • @JamesManning:这个问题有一段奇怪的历史。我的回答直到几个月前才被接受。但我的回答不好(ctorx 评论家非常有效)。然后问题所有者将接受移至此,这在您进行编辑之前是完全错误的。此外,它是DbContext 的答案,它比问题提出的要晚得多,问题中的代码 sn-ps 仍然适用于ObjectContext。现在您已将其编辑为DbContext 的正确答案,但现在与 ssmith 的答案相同,比一年多。但两者都不是ObjectContext 的答案。太疯狂了:)
      • @Slauma - 确实很疯狂!如果您的答案只是通过 ctor 重新生成而“关闭”,是否正在编辑它以在 MyEntitiesContext 的部分类中的“partial void OnContextCreated()”方法中执行 LazyLoadingEnabled = false 的“正确”修复/更改?对此感到抱歉 - 我可能应该把它单独留下。 :)
      • @JamesManning:是的,听起来不错。如果您用这个想法做出自己的答案,那将是最好的,并且可能会被接受:) 您也可以编辑我的答案...随心所欲。
      【解决方案5】:

      如果您是代码优先建模,只需删除引用/对象属性上的 virtual 关键字。在引用上使用 virtual 将在该特定引用上启用 LazyLoading。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-21
        相关资源
        最近更新 更多