我有这个,
Expression<Func<MyCourse, bool>> filter = mc => mc.Active == 1;
Func<MyCourse, bool> funcWhere = filter.Compile();
然后这个
var myClasses = db.MyCourse.Join(db.People, mc => mc.PersonId,
p => p.PersonId, (mc, p) => new { MyCourse= mc, Person = p }).Where(???)
之所以需要这样做,是因为如果我首先将过滤器放在MyCourse表上,
db.MyCourse.Where(funcWhere).Join....
创建的SQL将带回所有人员和所有MyCourse,然后使用过滤器。如果我在最后做
(mc, p) => new { MyCourse= mc, Person = p }).Where(mc=>mc.MyCourse.Active == 1)
我对Joins有很好的查询。否则,引擎首先将所有行查询到内存中。具有数千行的两个独立查询。
我已经在SO和其他地方看到了很多与此相关的问题。我找不到一个可以告诉我如何在多于一个表的情况下使用dynamic从Join进行表达式的操作Where Expression<Func<T,TResult>>
。
目标是根据表达式(而不是Dynamic Linq,并且没有第三方)来创建动态查询语句。实际上,该问题声称“ Where”结尾处较慢,但在我的程序中它使用Joins进行了正确的查询。
MyCourse具有一个PersonId,而People具有一个PersonId。如果我亲手写的话,
select mc.CourseName, p.LastName
from MyCourse mc inner join Person p on mc.PersonId = p.PersonId
where mc.Active = 1;
(这些只是问题的示例列。它们不是我在上述查询中真正想要的,除了Active ==1。)
更新:FWIW,我能够在此上运行它,
var param = Expression.Parameter(typeof(MyClass), "MyClassDebug");
var exp = Expression.Lambda<Func<MyClass, bool>>(
Expression.Equal(
Expression.Property(param, dbParameter),
Expression.Constant(dbValue)
),
param
);
我没有导航属性或其他任何内容。我能够这样使用它,
var MyQuery = (from recs in dbcontext.MyClass.Where(exp)
...three joins
产生的SQL看起来不错,并且Explain计划显示最少的行检索。
我怀疑打电话Compile()
给您Expression
会造成麻烦。您的完整查询包含Join
,但您已经编译了该Where
子句,因此它无法编译包括Join
一起的整个查询。这可能就是为什么它要抓住整个表的原因,因为它Where
首先自己执行,然后再执行Join
。
但是您不需要打电话Compile()
。只需将Expression
传入Where()
:
Expression<Func<MyCourse, bool>> filter = mc => mc.Active == 1;
var myClasses = db.MyCourse
.Where(filter)
.Join(db.People, mc => mc.PersonId,
p => p.PersonId, (mc, p) => new { MyCourse= mc, Person = p }).ToList();
某种程度上与您的实际问题无关,但是如果您创建了外键,则可以稍微简化一下。如果尚未更新模型,请在Visual Studio项目中进行更新。您的Person
班级将更改为具有一个列表,MyCourse
而您的MyCourse
班级将具有一个列表Person
。
因此,您可以执行以下操作:
Expression<Func<MyCourse, bool>> filter = mc => mc.Active == 1;
var courses = db.MyCourse.Include("Person").Where(filter);
foreach (var course in courses) {
var person = course.Person; //This is populated with the Person record
}
Linq处理联接,并且每个MyCourse
返回的对象都会有一个Person
属性。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句