为什么IQueryable上的.Where()返回一个不同的类型,基于Lamba或Func <T,Tresult>是否作为参数传递

Ale*_*exC 3 c# linq lambda linq-to-entities entity-framework

在我的Entity Framework Code First项目中,我有一个包含路由的存储库对象

public class EFRepository
{
    ...
    public IQueryable<Route> Routes
    {
        get { return context.Routes; }
    }
   ...
}
Run Code Online (Sandbox Code Playgroud)

如果我跑

var routes = this.repository.Routes
                  .Where(r => r.DeployedService.IsActive.HasValue 
                   && r.DeployedService.IsActive.Value);
Run Code Online (Sandbox Code Playgroud)

routes对象是类型IQueryable<Route>.

但是,如果我跑

Func<Route, bool> routeIsActive = r => r.DeployedService.IsActive.HasValue 
                                      && r.DeployedService.IsActive.Value;
var routes = this.repository.Routes.Where(routeIsActive);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,路由对象是类型IEnumerable<Route>.

我本以为他们会被评估相同,但显然我错了.两个语句之间有什么区别,为什么它们会返回不同的类型.

Dav*_*d M 5

该方法.Where(Expression<Func<Route,bool>>)IQueryable<Route>.定义..Where(Func<Route,bool>)另一方面,该方法由IEnumerable<Route>而不是由... 定义IQueryable<Route>.因此,每个返回自己的类型以进行流畅的LINQ方法链接.

定义的附加方法IQueryable允许将表达式树向下推送到LINQ提供程序,例如LINQ到实体,以便在提供者级别进行惰性后期评估,这是可能的.