我的 SQL 和实体框架知识有些有限。在一个实体框架 (4) 应用程序中,我注意到完成我的一个方法调用需要很长时间(大约 2 分钟)。第一个查询不需要太多时间,但是当我遍历查询返回的实体框架对象时,即使我只是读取(而不是修改)我应该得到的数据,完成嵌套循环也需要很长时间,即使每个列表中只有几十个条目和几级循环。
我希望下面的示例可以用更高级的查询重新编写,该查询可能包括我在循环中使用一些我真的不知道如何使用的 SQL 词进行的所有过滤,所以如果有人可以告诉我什么等效的 SQL 表达式将是,这对我来说非常有教育意义,并且可能解决我当前的性能问题。
此外,由于此应用程序的其他部分和我开发的其他应用程序经常想要对 SQL 数据进行更复杂的计算,我还想知道一种将数据从 Entity Framework 检索到本地内存对象的好方法,这些对象在读取时不会有很大的延迟他们。在我的 LINQ-to-SQL 项目中存在类似的性能问题,我通过重构整个应用程序以将所有 SQL 数据加载到 RAM 中的并行对象中解决了这个问题,我必须自己编写,我想知道是否没有一种更好的方法来告诉 Entity Framework 不要继续执行它正在执行的任何高延迟通信,或者加载到本地 RAM 对象中。
在下面的示例中,代码通过 SQL 查询获取某个成员(即人)在某个日期的食物菜单项列表,然后我使用其他查询和循环根据两个条件过滤掉菜单项: 1 ) 如果该成员对配方所属的任何组 id 的评分为零(多对多关系),并且 2) 如果该成员对配方本身的评分为零。
例子:
List<PFW_Member_MenuItem> MemberMenuForCookDate =
(from item in _myPfwEntities.PFW_Member_MenuItem
where item.MemberID == forMemberId
where item.CookDate == onCookDate
select item).ToList();
// Now filter out recipes in recipe groups rated zero by the member:
List<PFW_Member_Rating_RecipeGroup> ExcludedGroups =
(from grpRating in _myPfwEntities.PFW_Member_Rating_RecipeGroup
where grpRating.MemberID == forMemberId
where grpRating.Rating == 0
select grpRating).ToList();
foreach (PFW_Member_Rating_RecipeGroup grpToExclude in ExcludedGroups)
{
List<PFW_Member_MenuItem> rcpsToRemove = new List<PFW_Member_MenuItem>();
foreach (PFW_Member_MenuItem rcpOnMenu in MemberMenuForCookDate)
{
PFW_Recipe rcp = GetRecipeById(rcpOnMenu.RecipeID);
foreach (PFW_RecipeGroup group in rcp.PFW_RecipeGroup)
{
if (group.RecipeGroupID == grpToExclude.RecipeGroupID)
{
rcpsToRemove.Add(rcpOnMenu);
break;
}
}
}
foreach (PFW_Member_MenuItem rcpToRemove in rcpsToRemove)
MemberMenuForCookDate.Remove(rcpToRemove);
}
// Now filter out recipes rated zero by the member:
List<PFW_Member_Rating_Recipe> ExcludedRecipes =
(from rcpRating in _myPfwEntities.PFW_Member_Rating_Recipe
where rcpRating.MemberID == forMemberId
where rcpRating.Rating == 0
select rcpRating).ToList();
foreach (PFW_Member_Rating_Recipe rcpToExclude in ExcludedRecipes)
{
List<PFW_Member_MenuItem> rcpsToRemove = new List<PFW_Member_MenuItem>();
foreach (PFW_Member_MenuItem rcpOnMenu in MemberMenuForCookDate)
{
if (rcpOnMenu.RecipeID == rcpToExclude.RecipeID)
rcpsToRemove.Add(rcpOnMenu);
}
foreach (PFW_Member_MenuItem rcpToRemove in rcpsToRemove)
MemberMenuForCookDate.Remove(rcpToRemove);
}