如何在Join之后的两个表的Where子句中为Linq创建Lambda表达式?

强尼

我有这个,

 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。)

带Lambda表达式中的Join的where子句

更新: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计划显示最少的行检索。

加布里埃尔·卢西(Gabriel Luci)

我怀疑打电话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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在带有Join的EF Where()子句中使用表达式树?

如何在ASP.Net MVC中使用LINQ lambda表达式在视图中显示两个表的数据?

如何在Codeigneitor的get_where子句中联接两个表数据

使用 Linq 在 WHERE 子句中构建 OR 表达式

带Lambda表达式中的Join的where子句

如何在JavaScript中将两个正则表达式合二为一?

如何在Laravel中查询的WHERE子句中使用正则表达式?

通过where子句分组,两个表达式都必须正确?

为LINQ to Entities Where子句构建表达式树

如何在MySQL where和where子句中的语句中使用正则表达式

来自两个表的where子句中的count()

如何使用 Linq lambda 表达式在两个列表之间获得相等和不相等的值

Mysql-如何在where子句中的不同表的两个字段上添加

如何在lambda表达式中的not in子句中写入not in子句,该子句中不包含其他模型列表中的值

如何在单个 SQL 语句的 where 子句中使用两个 LIKE?

如何仅通过表达式创建where子句

在对两个表进行LEFT JOIN后,如何用不满足WHERE子句中条件的NULL值保留行

通过Lambda表达式检索两个或多个表中的数据

在 Linq 中检查具有布尔数据类型的 where 子句中的两个条件时,List 为空

where子句之后的两个条件

如何使用一个表达式与 lambda 合并两个计数值?

Lambda表达式遍历两个并发字典

将两个lambda与表达式相乘

Lambda表达式中的两个for循环

SQLite3-使用两个表的复杂WHERE表达式

LINQ 中两个 Lamba 表达式的区别

如何使用“ as”子句修复“必须为聚合表达式或出现在GROUP BY子句中”

JS 正则表达式。如何将两个表达式合二为一?

如何将两个case值表达式重构为一个?