如何从Entity Framework导航属性创建LINQ表达式?

时间:2009-05-27 22:57:54

标签: linq entity-framework linq-to-entities lambda

我有以下代码:

Expression<Func<Subscription, Service>> service2= subscription => (from relationship in subscription.ChildRelationships
    select relationship.SecondService).FirstOrDefault();

它创建了一个表达式,我稍后可以将其用作实体框架的查询的一部分。我正在使用的实际代码有一个where子句,但为了便于阅读,我省略了它。这很好用,我可以在LINQPad中运行它,我正在用它进行测试。

如果我将代码更改为:

Expression<Func<Subscription, IQueryable<Service>>> service2= subscription => (from relationship in subscription.ChildRelationships
    select relationship.SecondService);

它不再编译并出现以下错误:

  

无法将lambda表达式转换为   代表类型   'System.Func&LT; Farmworks.Data.Subscription,System.Linq.IQueryable&LT; Farmworks.Data.Service&GT;&GT;'   因为一些返回类型   块不是隐含的   可转换为代表返回   型

这似乎是因为作为导航属性的ChildRelationships没有实现IQueryable。它实际上是EntityCollection类型,它实现了IEnumerable,但不适合创建与EF一起使用的表达式。

我想我理解为什么第二块代码不起作用,并且想知道如何重写它以便它做到。令我困惑的是为什么第一块代码确实有效。它还使用ChildRelationships导航属性,但在成为与EF一起使用的表达式时没有任何问题。

任何人都可以放弃任何光明吗?

3 个答案:

答案 0 :(得分:1)

问题不在于FirstOrDefault以某种方式使Expression工作;正如你所说的那样,ChildRelationships本身并没有实现IQueryable。您可以根据自己的需要以两种不同的方式解决这个问题。

您可以使用IEnumerable.AsQueryable方法。如果服务已经从上下文加载,这可能是最好的。

如果未加载服务,您可以根据需要使用Load或Include方法在适当的时候加载它们,然后使用上面的解决方案。

如果你有对ObjectContext的引用,你可以使用ObjectQuery,它实现了IQueryable:

Expression<Func<Subscription, MyEntities, IQueryable<Service>>> service2 = 
    (subscription, context) => (
    from s in context.Subscriptions // here is the IQueryable
    where s.Id == subscription.Id
    from relationship in s.ChildRelationships
    select relationship.SecondService);

答案 1 :(得分:0)

我认为CompiledQuery课程在这种情况下可以帮到你:

Expression<Func<Subscription, IQueryable<Service>>> service2 = 
    CompiledQuery.Compile( 
        subscription => (
            from relationship in subscription.ChildRelationships
            select relationship.SecondService
        )
    );

答案 2 :(得分:0)

你需要它是IQueryable&lt; Service&gt;?我认为select正在返回IEnumerable&lt; Service&gt;。 LINQ直接在IEnumerables上运行,因此您可以将service2声明为Expression&lt; Func&lt; Subscription,IEnumerable&lt; Service&gt;&gt;&gt ;.