C# 什么决定了Linq语句中的Where可以解析什么?

C# 什么决定了Linq语句中的Where可以解析什么?,c#,linq,linq-query-syntax,C#,Linq,Linq Query Syntax,在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

在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;
编译器抱怨

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

我见过很多这样的问题,但我不明白为什么它不起作用。我理解基本原理,所以我不是真的要求任何人编写代码。我想知道Linq想要什么,所以我对Linq有了更好的理解,而不仅仅是让某些东西起作用。例如,这是有效的

  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,编译器仍然知道MyRecords字段,包括Active

我想这就是我想要的一个恰当的描述,因为它似乎非常符合我的想法


在第一个示例中应用的过滤器类型错误。blue linq语法为您提供了很多帮助,使此查询易于阅读。实际发生的事情是创建一些匿名类型,其中包含对项目的引用。注意,在where子句中,还可以使用
p
cse
变量。当你把它考虑到你的表达式中时,你可能会认为它是这样的
expression你的过滤器在第一个例子中应用的类型是错误的。blue linq语法为您提供了很多帮助,使此查询易于阅读。实际发生的事情是创建一些匿名类型,其中包含对项目的引用。注意,在where子句中,还可以使用
p
cse
变量。当您将其考虑到表达式中时,您可能会认为它是这样的
expression过滤器失败了,因为Where需要表达式的匿名版本,而我已经提供了System.Func。它需要System.Func筛选器失败,因为Where需要表达式的匿名版本,而我已提供System.Func。它需要System.Func
  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 });
  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 });
(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)