C# 4.0 性能问题:如何同时执行两个lambda表达式&引用;包括「;及;任何;操作员使用
示例代码C# 4.0 性能问题:如何同时执行两个lambda表达式&引用;包括「;及;任何;操作员使用,c#-4.0,lambda,asp.net-mvc-4,entity-framework-5,C# 4.0,Lambda,Asp.net Mvc 4,Entity Framework 5,示例代码 var Ids = _db.Projects.Where(Project=>Project.Title!="test23rdoct") .Select (pro => pro.Id); Expression<Func<Company, bool>> masterExpression = Company => Company.Participants.Any(part => ids.Contains(part.Proje
var Ids = _db.Projects.Where(Project=>Project.Title!="test23rdoct")
.Select (pro => pro.Id);
Expression<Func<Company, bool>> masterExpression =
Company => Company.Participants.Any(part => ids.Contains(part.Project.Id));
IQueryable<Object> queryEntity = _db.Companies.Where(masterExpression)
var id=_db.Projects.Where(Project=>Project.Title!=“test23rdoct”)
.选择(pro=>pro.Id);
表达式主表达式=
Company=>Company.Participants.Any(part=>Id.Contains(part.Project.Id));
IQueryable查询实体=_db.companys.Where(masterExpression)
上述查询将执行两次。在服务器中存储ID(有时ID超过50k计数)。它会导致性能问题。有谁能建议如何将这两个查询合并并立即执行吗?如何:
var queryEntity = _db.Companies.Where(c => c.Partipants.Any(p => p.Project.Title != "test23rdoct"));
编辑:
使用复杂查询,您还可以拆分:
Func<Project, bool> projectFilter = Project => ((Compare(Convert(Project.Title), "a") > 0) AndAlso ((Convert(Project.Title) != "test23rdoct") AndAlso
(Project.Participants.Any(Participant => (Compare(Convert(Participant.ParticipantRole.Name), "Finance") > 0)) AndAlso
(Project.Participants.Any(Participant => (Convert(Participant.Person.FirstName) != "test1")) AndAlso
Project.Participants.Any(Participant => (Compare(Convert(Participant.Company.Name), "test") > 0))))));
使用
Join
这样的功能是否适合您的需要
Expression<Func<Company, bool>> masterExpression =
Company => Company.Participants.Join (Ids, p => p.Project.ID, id => id, (p, id) => p).Any();
IQueryable<Object> queryEntity = _db.Companies.Where(masterExpression);
表达式主表达式=
Company=>Company.Participants.Join(ID,p=>p.Project.ID,ID=>ID,(p,ID)=>p.Any();
IQueryable查询实体=_db.companys.Where(masterExpression);
我得到这个解决方案是为了避免两次执行Lambda。为了实现这一点,我使用了以下扩展方法Invoke()和AsExpandable()。它在Linqkit dll中可用
Expression<Func<Company, bool>> masterExpression = Company => Company.Participants.Any(part => masterLamba.Invoke(part.Project));
queryEntity = _db.Companies.AsExpandable().Where(masterExpression);
Expression masterExpression=Company=>Company.Participants.Any(part=>masterLamba.Invoke(part.Project));
queryEntity=_db.companys.AsExpandable().Where(masterExpression);
它不起作用。我不想更改此表达式Project=>Project.Title=“test23rdoct”。它是动态的。你说它不工作是什么意思?当您说动态时,您的意思是“test23rdoct”值是可变的吗?获取Ids查询将是动态的,如下所示。Project=>((比较(转换(Project.Title),“a”)>0)和also((转换(Project.Title)!=“test23rdoct”)和also(Project.Participants.Any)(参与者=>(比较(转换(Participant.Participant.Name),“Finance”)>0)和also(Project.Participants.Any)(参与者=>(转换(Participant.Person.FirstName)!“test1”))AndAlso Project.Participants.Any(Participant=>(Compare(Convert(Participant.Company.Name),“test”)>0‘‘‘‘‘‘‘)’)Pablo,谢谢。看起来它接近于我所寻找的解决方案。我在执行lambda“LINQ to Entities中不支持LINQ表达式节点类型‘Invoke’”时遇到了此异常。没错,EF不知道如何转换任意表达式。为什么你要把它们分开,你是在用一些工具建立那些条件吗?这里你没有提到获取ID的表达式。这是一个获取ID的简单查询,Project=>Project.Title=“test23rdoct”。它可以是大的,就像在上一篇文章中回答的那样。您已经在Ids
查询中按ID子句进行筛选,这是Join
的第一个参数(我将其编辑为大写)。它将在连接期间进行延迟计算。如果将其设置为动态,则可以根据需要将Ids查询作为Func
参数传入。我把问题的重点放在如何结合这两个问题上。这些构造将作为单个SQL查询运行。是包含的
子句需要两次db调用。很抱歉回复太晚。我不希望ID作为单独的查询执行。我只是希望在加入这个查询时也应该执行id。基本上我不想在内存中存储任何东西。我可以分享你的想法,我怎样才能动态获取ID?
Expression<Func<Company, bool>> masterExpression = Company => Company.Participants.Any(part => masterLamba.Invoke(part.Project));
queryEntity = _db.Companies.AsExpandable().Where(masterExpression);