2017-06-02 66 views
1

我写它看起来像这样的代码:加快LINQ查询(从表中选择数据)

using(var ctx = new myentitiesContext()) 
{ 
    var currentLoggedUser = ctx.Users.FirstOrDefault(x=>x.Email==User.Identity.Name); 
    var items = ctx.Items.Where(x=>x.Sales>0 && x.UserId==currentLoggedUser.UserId).ToList(); 
} 

正如你可以看到它是从数据库中一个简单的选择。但棘手的部分是,有时我可以选择大量的数据(一次50-100k条记录)。所以我一直在想,有什么方法可以调整LINQ在数据被从表中拉出时更快地执行?

我已经在我的表中创建了FK UserId中的索引,因此部分完成了。

我的问题是,有没有什么办法可以通过上下文配置部分的一些调整来加速LINQ查询,或者通过创建编译查询或者通过其他方法来加速LINQ查询?

P.S.球员,会这样的工作很好:

ctx.Configuration.AutoDetectChangesEnabled = false; 

    // my queries... 

    ctx.Configuration.AutoDetectChangesEnabled = true; 
+2

有各种方法可以告诉EF采取一些快捷方式,例如'AutoDetectChanges'标志和'.AsNoTracking()',但加速查询的绝对最佳方式是避免调用'.ToList()'直到您需要内存中所有元素的实际列表(在任何过滤器运行之后)。 – Scott

+0

@Scott The .AsNoTracking是我的对象上下文的扩展方法吗? – User987

+1

“用户”的主键是什么?如果你使用Find来代替FirstOrDefault,那么你可以节省一些时间。我也建议将主键值对用户的身份进行缓存,以防止不断查找它。 – Clint

回答

1

此外还有其他用户编写的内容。您可以禁用延迟加载。这样,如果Items Db Table引用了其他表,除非你绝对需要它们,否则它们将不会与该Items一起加载。检查这些链接

  1. thecodegarden
  2. mehdi

还有一个认为我会建议是,你必须登录,您的LINQ表达式创建SQL查询,并尝试与你的DBA对其进行优化。您可以通过在DbContext.Database.Log上添加Action<string>代表来执行此操作,该代表将发出connection.Open()connection.Close()之间的所有内容。您还可以从您的IQueryableIQueryable<T>中取出sql查询,并在您的IQueryable变量上调用.ToString()方法。

-2

你应该先做投影。例如,这样的:

var items = ctx.Items.Where(x=>x.Sales>0 && x.UserId==currentLoggedUser.UserId).ToList(); 

会更好,如果你写这样的:

var items = ctx.Items.Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0).ToList(); 

如果你并不需要所有的对象你之前,使用“选择”条款“Where”和项目只是你需要降低成本的属性,如下所示:

ctx.Items.Select(e=>new {e.UserID,e.Sales}).Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0).ToList(); 
+1

实际上,当与数据库交谈时,没有任何问题。 – NetMage