调用表达式

问题描述:

这就是我想做的事:调用表达式

class MyDbContext : DbContext 
{ 
    private static Expression<Func<MyClass, int>> myExpression1 = x => /* something complicated ... */; 
    private static Expression<Func<Item, int>> myExpression2 = x => /* something else complicated ... */; 

    public object GetAllData() 
    { 
     return (
      from o in MyClassDbSet.AsExpandable() 
      select new 
      { 
       data1 = myExpression1.Invoke(o),      // problem 1 
       data2 = o.Items.Select(myExpression2.Compile())  // problem 2 
      } 
     ); 
    } 
} 

UPDATE:

myExpression已经远离我的查询分开,因为我想重新使用它在多个LINQ查询中。

更新2:

分居myExpressionmyExpression1myExpression2明确指出,我想单独重用他们的事实。

UPDATE 3:

添加LINQkit实施例。

问题1抛出:无法投入类型为“System.Linq.Expressions.FieldExpression”的对象以键入“System.Linq.Expressions.LambdaExpression”。

问题2抛出:内部的.NET Framework数据提供程序错误1025

+0

看一看[LINQKit(http://www.albahari.com/nutshell/linqkit.aspx)。 – svick

+0

谢谢,我会试试! – billy

+0

@svick,我更新了问题,以反映我现在正在使用LINQkit的问题... – billy

您可以尝试使用仅代表不是表达式:

private static Func<MyClass, int> myExpression = x => /* something complicated ... */; 

这种方法的问题,就是整个MyClass将从数据库中检索,而不是只需要计算表达式的字段。

+0

更新的问题,显示为什么我不想那么... – billy

关于使用LinqKit时的第一个问题,你需要在.Invoke()之前将你的表达式赋值给一个局部变量。更完整的解释可以在this question找到。

的第二个问题是,选择方法接受类型的对象:

Expression<Func<TSource, TResult>> 

这意味着必须提供lambda表达式接受TSource对象作为参数并返回一个TResult对象。

您的TSource对象是Item,也就是您正在查询的表。你的TResult在你的例子中是一个int,这是你在表达式上定义的。

因此,您必须以传递MyClassDbSet对象“o”的相同方式,在传递Item对象作为参数的第二个表达式上调用.Invoke()。实际上,这两种选择语句在语法上都存在差异,它们本质上是做同样的事情。

,你不应该呼吁表达.Compile(),这将产生一个:

Func<TSource, TResult> 

这是一个代表对表达式树的编译版本并不能转换成SQL表达式。更多的信息可以在here找到。

应该有以下变化工作:

class MyDbContext : DbContext 
{ 
    private static Expression<Func<MyClass, int>> myExpression1 = x => /* something complicated ... */; 
    private static Expression<Func<Item, int>> myExpression2 = x => /* something else complicated ... */; 

    public object GetAllData() 
    { 
     Expression<Func<MyClass, int>> myLocalExpression1 = myExpression1; 
     Expression<Func<MyClass, int>> myLocalExpression2 = myExpression2; 

     return (
      from o in MyClassDbSet.AsExpandable() 
      select new 
      { 
       data1 = myLocalExpression1.Invoke(o), 
       data2 = o.Items.Select(item => myLocalExpression1.Invoke(item)) 
      } 
     ); 
    } 
} 
+0

谢谢,我会尝试局部变量.. 。 – billy