Entity Framework:如何禁用特定查询的延迟加载?

100

有没有办法在Entity Framework 6的特定查询中禁用延迟加载?我想要经常使用它,但有时我想禁用它。我正在使用虚拟属性来进行延迟加载。


22
在你想要运行的查询之前,设置context.Configuration.LazyLoadingEnabled = false;。 - Karthik Ganesan
6
你可以直接设置值this.Configuration.LazyLoadingEnabled = false;,然后再将其设置为this.Configuration.LazyLoadingEnabled = true;吗?此外,你还可以阅读http://msdn.microsoft.com/en-us/data/jj574232.aspx。 - user1477388
1
谢谢@KarthikGanesan。它按预期工作了。 - Marco Alves
@KarthikGanesan,您能把您的评论作为答案吗?它真的很有效 :) - Sampath
1
将注释添加为答案@Sampath - Karthik Ganesan
这是一个奇怪的问题。查询从不执行延迟加载。延迟加载是关于当导航属性被访问时EF自身触发的查询。因此,在一个查询期间禁用延迟加载是无用的。这个问题归结为:如何完全禁用延迟加载。 - Gert Arnold
9个回答

89
在你想要执行的查询之前,设置以下代码。
context.Configuration.LazyLoadingEnabled = false;

42

您可以按照以下方式为特定查询禁用惰性加载:

public static Cursos GetDatosCursoById(int cursoId)
{
    using (var bd = new AcademyEntities())
    {
        try
        {
            bd.Configuration.ProxyCreationEnabled = false;
            return bd.Cursos.FirstOrDefault(c => c.cursoId == cursoId);
        }
        catch (Exception ex)
        {
            return null;
        }
    }
}

30

也许我在这里漏掉了什么,但是除了每次更改配置之外,另一种方法是否可以是仅在想要急切加载的查询上使用.Include()

假设我们有一个Product类,它具有导航属性到一个Colour类,您可以像这样为Product加载Colour-

var product = _context.Products
    .Where(p => p.Name == "Thingy")
        .Include(x => x.Colours)
        .ToList();

2
对我来说,这是这里最好的答案! - Ian
1
如果你只想预加载“products”而没有包含任何内容,这就不够用了。 - Mackan
你想要获取“产品”而不带任何相关对象,还是“带有所有相关对象的产品?” - Parrybird
2
更有用的答案。这控制了在构建查询时加载的特定子表。对于任何现实世界的问题,这都必须是正确的方法。 - Richard Petheram
6
用另一种方式,它的作用也是很有用的……如果按这种方式做,仍然可以对“产品”中的另一个集合实现惰性加载。事实上,禁用惰性加载更为有效,可以确保提前获取所有所需数据并避免创建隐藏的性能瓶颈。 - Doug
如果我没有关闭懒加载并使用include,会发生什么?有人能告诉我它会如何表现吗? - Sumesh Es

23
在EF Core中:context.ChangeTracker.LazyLoadingEnabled = false; 根据这个答案

2
在这里提一下是有用的,EF Core 中的延迟加载除非显式配置,否则永远不会发生。然后,它可以在个别情况下关闭。 - Gert Arnold
EF Core的代码在你的EF项目是.Net Framework时也能正常工作。 - Cameron Castillo

16

前往您的图表属性,找到一个指定为懒加载的属性并将其禁用。

如果您正在使用 Code First,则请转至配置区域并通过以下方式在那里禁用它:

this.Configuration.LazyLoadingEnabled = false;

7
很多人正在访问这个问题,我想说的是,写查询之前一定要看执行计划。始终要知道你的代码发送给数据库的内容,否则你会遇到性能问题。你可以使用linq pad或其他工具查看实际查询并进行检查。 - Juan

5

另一种处理EF版本(Entity Framework 5)的方法

//Note: ContextOptions instead of ChangeTracker or Configuration
context.ContextOptions.LazyLoadingEnabled = false; 

2

如果您想要使用一种简单的方法来使用EF Core,您可以使用以下辅助工具:

public static AppDbContext DisableLazyLoading(this AppDbContext dbcontext)
{
     dbcontext.ChangeTracker.LazyLoadingEnabled = false;

     return dbcontext;

}

使用

 return dbcontext.DisableLazyLoading().Branches.Find(course.BranchId);

请查看我上面的评论。禁用惰性加载只是为了执行查询并不是真正有用的方法。这种方法强烈暗示了这正是发生的事情(因为它很流畅,看起来像AsNoTracking,它确实会改变一个查询的行为)。实际上,它只是像启用惰性加载一样执行查询,但它在其余的生命周期中关闭了上下文的惰性加载。它的使用方式是具有欺骗性的。 - Gert Arnold

2
假设你有这样一个代码段:
IOrderedQueryable<Private.Database.DailyItem> items;
using (var context = new Private.Database.PrivateDb())
{
    context.Configuration.LazyLoadingEnabled = false;
    items = context.DailyItem.OrderBy(c => c.sortOrder).OrderByDescending(c => c.isFavorite);
}

即使明确设置为不使用懒加载,您仍将得到懒加载。修复方法很简单,将其更改为:

List<Private.Database.DailyItem> items;
using (var context = new Private.Database.PrivateDb())
{
    // context.Configuration.LazyLoadingEnabled = false;
    items = context.DailyItem.OrderBy(c => c.sortOrder).OrderByDescending(c => c.isFavorite).ToList();
}

0
我只是在每个需要禁用延迟加载的类中这样做,在每个类中调用数据库而不进行延迟加载,一切都正常工作。
    private DataContext db;

    public TheClass ()
    {
        db = new DataContext(ConString);
        db.Configuration.LazyLoadingEnabled = false;
    } ​

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接