C# 加快LINQ查询(从表中选择数据)
我编写了一个代码,如下所示:C# 加快LINQ查询(从表中选择数据),c#,asp.net,asp.net-mvc,linq,c#-4.0,C#,Asp.net,Asp.net Mvc,Linq,C# 4.0,我编写了一个代码,如下所示: 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(
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();
}
var items = ctx.Items.Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0 ).ToList();
ctx.Items.Select(e=>new {e.UserID,e.Sales}).Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0 ).ToList();
正如您所看到的,这是从数据库中进行的简单选择。但棘手的是,有时我可以选择大量数据(一次选择50-100k条记录)。所以我一直在想,当数据从表中取出时,有没有办法调整LINQ以更快地执行
我已经在我的表中创建了关于FK UserId的索引,所以这部分已经完成了
我这里的问题是,有没有办法通过上下文配置部分中的一些调整,或者通过创建编译查询,或者通过其他方法来加速LINQ查询
伙计们,你们喜欢这个工作吗
ctx.Configuration.AutoDetectChangesEnabled = false;
// my queries...
ctx.Configuration.AutoDetectChangesEnabled = true;
你应该先做投影。例如,这:
var items = ctx.Items.Where(x=>x.Sales>0 && x.UserId==currentLoggedUser.UserId).ToList();
如果你这样写会更好:
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();
}
var items = ctx.Items.Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0 ).ToList();
ctx.Items.Select(e=>new {e.UserID,e.Sales}).Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0 ).ToList();
如果您不需要所有对象,则必须在“Where”之前使用“Select”子句,并仅投影您需要的属性以最小化成本,如下所示:
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();
}
var items = ctx.Items.Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0 ).ToList();
ctx.Items.Select(e=>new {e.UserID,e.Sales}).Where(x.UserId==currentLoggedUser.UserId).Where(x2=>x2.Sales>0 ).ToList();
除此之外,还有其他用户编写的内容。您可以禁用延迟加载。这样,如果Items Db表有对其他表的引用,除非您绝对需要,否则它们不会与这些项一起加载。检查这些链接
我还建议您记录linq表达式创建的sql查询,并尝试使用DBA对其进行优化。您可以通过在
DbContext.Database.Log
上添加一个Action
委托来实现这一点,该委托将在connection.Open()
和connection.Close()之间发出所有信息。您还可以从IQueryable
或IQueryable
调用.ToString()
方法对IQueryable
变量执行sql查询 有多种方法可以告诉EF使用一些快捷方式,例如自动检测更改标志和.AsNoTracking()
,但加速查询的绝对最佳方法是避免调用.ToList()
,直到需要内存中所有元素的实际列表(在运行任何筛选器之后)@Scott.AsNoTracking是我的对象上下文的一种扩展方法。用户的主键是什么?如果使用Find
而不是FirstOrDefault
,很可能可以节省一些时间;我还建议根据用户的身份缓存主键值,以防止不断查找。@User987 yes。理想情况下,针对Identity对象本身(您可以从GenericEntity
派生来实现您自己的值)@User987我实际上从未使用过编译查询的东西,但我没有想到它会提供太多的提升,但这一切都取决于您自己的评测以及对您有用的东西。我建议您调查一下这些问题,然后打开一个新的SO问题来解决您与他们之间的任何问题:)事实上,在与数据库交谈时,这些都不重要。