是什么决定了Linq语句中的Where能够解析什么



在Linq语句的Where子句中,

var myClasses = (from b in db.MyRecords
join p in db.People on b.PersonId equals p.PersonId
join cse in db.Courses on b.CourseId equals cse.CourseId
where (b.Active == 1)
select new { b });

表达式b.Active==1运行良好。但如果我这样做,

Expression<Func<MyRecords, bool>> filter = my => my.Active == 1;

[更新:由于Hans的回答,我保留了原来的答案,但实际上,我在这里打错了。表达式实际上使用的是底层类型,而不是像查询Linq那样EF生成的复数。我实际上有这个,

Expression<Func<MyRecord, bool>> filter = my => my.Active == 1;

]

试试这个,

var myClasses = (from b in db.MyRecords
join p in db.People on b.PersonId equals p.PersonId
join cse in db.Courses on b.CourseId equals cse.CourseId
where (filter)
select new { b });

编译器抱怨,

无法将查询表达式转换为预期的委托类型,因为块中的个返回类型不能隐式转换为委托返回类型

我看到了很多关于这个的SO问题,但我不明白为什么它不起作用。我误解了基本原理,所以我并没有真正要求任何人编写代码。我想知道林克想要什么,这样我对林克有了更好的了解,而不仅仅是让一些东西发挥作用。例如,

var myClasses = (from b in db.MyRecords.Where(filter)
join p in db.People on b.PersonId equals p.PersonId
join cse in db.Courses on b.CourseId equals cse.CourseId
select new { b });

我想知道为什么它在那里有效,而在加入后的Where中无效。如果我在联接结束时执行Where,编译器仍然知道MyRecords字段,包括Active。

认为这就是我想要的正确描述,因为它似乎很适合我。

http://www.albahari.com/nutshell/linqkit.aspx

您的过滤器只是第一个示例中应用的类型错误。blue-linq语法为您提供了很多神奇的功能,使该查询易于阅读。实际情况是创建一些匿名类型,其中包含对项目的引用。请注意,在where子句中,还可以使用pcse变量。当你把它考虑到你的表达式中时,你可能会认为它像这个Expression<Func<Tuple<MyRecords, People, Courses>>,实际上它不是一个元组,而是一些匿名类型。

当你要求重新arper将蓝色语法转换为方法链时,它会生成这样的代码:

(db.MyRecords.Join(
db.People, 
b => b.PersonId,
p => p.PersonId,
(b, p) => new {b, p})
.Join(
db.Courses,
t => t.b.CourseId, 
cse => cse.CourseId,
(t, cse) => new {t, cse})
.Where(t => (t.t.b.Active == 1))
.Select(t => new {t.t.b}));

实际上,你不能像以前那样在蓝色语法中使用过滤变量:

... join cse in db.Courses on b.CourseId equals cse.CourseId
where (filter)

您必须切换到方法调用:

(from b in db.MyRecords
join p in db.People on b.PersonId equals p.PersonId
join cse in db.Courses on b.CourseId equals cse.CourseId
select b)
.Where(filter)

现在,因为我们将内部查询修剪为仅b,所以您可以应用过滤器。

相关内容

  • 没有找到相关文章

最新更新