我正在使用MVC4和Entity Framework 5进行项目。我们有一个名为MAIN_TABLE
的主表,并且有几个子表(即:CHILD_TABLE1
,CHILD_TABLE2
等。)
由于这些不同子表中的过滤选项很少,我们面临着LINQ查询执行速度的问题。
我必须编写一个查询,使用EF5从Model中过滤数据。 现在我们一次基于单个过滤器进行编码。即我们正在检查每个过滤的列并触发查询。但它太慢了。还有其他选择吗?
string[] strValue = filter_Values;
foreach (SelectedData selectedData in objSelectedDataCollection.DataCollection)
{
switch (selectedData.ColumnName) // This is the column name in the GridView defined
{
case "Outlook":
indlist = from jd in indlist
where jd.IND_APP_PASS_STATUS.Any(
ob => strValue.Contains(ob.Outlook))
orderby jd.Indman_ID
select jd;
break;
case "RS_TP":
indlist = from jd in indlist
where jd.IND_APP_PASS_STATUS.Any(
ob => strValue.Contains(ob.RS_TP))
orderby jd.Indman_ID
select jd;
break;
case "Code":
indlist = (from jd in indlist from jk in jd.IND_APP_PASS_STATUS where strValue.Contains(jk.Code) select jd).ToList();
break;
}
}
答案 0 :(得分:1)
EF性能有两个方面 - 服务器和客户端(您的应用程序)。
首先,正如评论中提到的那样,使用SQL分析器来查看生成的查询执行速度有多快。
还要注意返回的记录数。对于返回特别大的结果集switching automatic changes detection off的查询,暂时can give可以显着提升性能。
答案 1 :(得分:1)
从您的评论中,初始数据库查询是
indlist = db.IND_TABLE
.ToList()
.Where(x => x.Package_No.Trim() != "")
.OrderBy(x => Int32.Parse(x.Package_No))
.Select(x => x)
.ToList<IND_TABLE>();
第一个.ToList()
表示将从数据库返回整个IND_TABLE
。然后在代码中完成所有其他过滤。这是性能不佳的原因之一 - 过滤数据库几乎总是比返回所有内容更好。
另请注意,您要多次对结果进行排序。首先设置indlist
,然后在objSelectedDataCollection.DataCollection
的每次迭代中设置一次。这是不必要的,在完成过滤之前,您根本不应该排序。也许在foreach
循环之后,你可以有一行indlist = indlist.OrderBy(x => x.Indman_ID);
将所有这些放在一起可以得到以下结果。
var indlist = db.IND_TABLE
.Where(x => x.Package_No.Trim() != "");
string[] strValue = filter_Values;
foreach (SelectedData selectedData in objSelectedDataCollection.DataCollection)
{
switch (selectedData.ColumnName)
{
case "Outlook":
indlist = indlist.Where(il => il.IND_APP_PASS_STATUS.Any(iaps => strValue.Contains(iaps.Outlook)));
break;
case "RS_TP":
indlist = indlist.Where(il => il.IND_APP_PASS_STATUS.Any(iaps => strValue.Contains(iaps.RS_TP)));
break;
case "Code":
indlist = indlist.Where(il => il.IND_APP_PASS_STATUS.Any(iaps => strValue.Contains(iaps.Code)));
break;
}
}
indlist = indlist.OrderBy(x => x.Indman_ID).ToList();
当实体框架创建用于查询数据库的SQL(搜索术语&#34;延迟执行&#34;)时,值得一读。只有当您尝试使用结果时才会发生这种情况 - 例如ToList()
,ToArray()
,SingleOrDefault()
和其他各种事情。行context.TableName.Where(some lambda expression);
在此时不会导致数据库查询。您可以在没有数据库调用的情况下使用Where
继续过滤,这就是我发布的代码中发生的事情。只会生成SQL并在行indlist = indlist.OrderBy(il => il.Indman_ID).ToList();
答案 2 :(得分:0)
问题出在我写的查询中。
请检查以下查询。现在我使用&#39;加入&#39;而不是在子表中查询。
注意:答案是如果我们使用Subtables编写查询,则每个父行都会命中数据库中的每个子表行。因此,您的代码性能将根据行数减少.i.e。如果子表有10行,它将对数据库命中10次。但如果我们正在使用&#39;加入&#39;现在,两个表之间的代码只会在每列中出现一次。
var indlist = db.IND_TABLE
.Where(x => x.Package_No.Trim() != "");
string[] strValue = filter_Values;
foreach (SelectedData selectedData in objSelectedDataCollection.DataCollection)
{
switch (selectedData.ColumnName)
{
case "Outlook":
indlist = (from jd in indlist join ipas in dbContext.IND_APP_PASS_STATUS on jd.Indman_ID equals ipas.Indman_ID where (strValue.Contains(ipas.Outlook)) orderby jd.Indman_ID select jd).ToList<IND_TABLE>();
break;
case "RS_TP":
indmanlist = (from jd in indmanlist join ipas in dbContext.IND_APP_PASS_STATUS on jd.Indman_ID equals ipas.Indman_ID where (strValue.Contains(ipas.RS_TP)) orderby jd.Indman_ID select jd).ToList<IND_TABLE>();
break;
case "Code":
indmanlist = (from jd in indmanlist join ipas in dbContext.IND_APP_PASS_STATUS on jd.Indman_ID equals ipas.Indman_ID where (strValue.Contains(ipas.Code)) orderby jd.Indman_ID select jd).ToList<IND_TABLE>();
break;
}
}
我曾使用SQL Profiler检查数据库的执行情况。然后我意识到了打到数据库的真正问题。