将委托传递给CompiledQuery.Compile方法

时间:2011-02-26 19:39:47

标签: c# linq-to-sql

在尝试将委托System.Func<T,TResult>传递给CompiledQuery.Compile方法时,我收到以下错误

错误1无法从用法中推断出方法'System.Data.Linq.CompiledQuery.Compile(System.Linq.Expressions.Expression&gt;)'的类型参数。请尝试明确指定类型参数“。

public static void CompiledLINQQuery()
{
    Northwind_LINQtoSQLDataContext objData = new Northwind_LINQtoSQLDataContext();
    Func<Northwind_LINQtoSQLDataContext, IQueryable<Customer>> LINQHolder = GetPreCompiledQuery;

    LINQHolder = CompiledQuery.Compile(LINQHolder); //This is where the error comes up           
    var Results = LINQHolder.Invoke(objData);   
}

private static IQueryable<Customer> GetPreCompiledQuery(Northwind_LINQtoSQLDataContext objD)
{
    return from cust in objD.Customers where cust.Country == "Germany" select cust;
}

同时,如果我将LINQ直接传递给CompiledQuery.Compile方法,那么它的工作没有任何错误。

LINQHolder = CompiledQuery.Compile((Northwind_LINQtoSQLDataContext objD) => from cust in objD.Customers where cust.Country == "Germany" select cust);

我不明白为什么我无法传递委托而不是LINQ查询表达式。

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:1)

CompiledQuery.Compile()仅在Expression&lt; Func&lt;&gt;&gt;上定义,但不在Func&lt;&gt;

上定义

如果您将语句重写为

,您的代码是否会编译
var LINQHolder = GetPreCompiledQuery;
var CompiledLINQHolder = CompiledQuery.Compile(LINQHolder); 

答案 1 :(得分:1)

您无法传递委托,因为方法签名指定了表达式树,而不是委托 - 它就像那样简单。它们是两种截然不同的类型。

它们的共同点 - 以及最后一段代码将编译的原因 - 是编译器可以将 lambda表达式转换为委托或表达式树。现在,这不是你在第一种情况下创建委托的方式 - 你实际上是在使用方法组转换。那永远不会创建表达式树。

如果要在单独的方法中指定查询,则必须是这样的:

private static Expression<Func<Northwind_LINQtoSQLDataContext,
                               IQueryable<Customer>>
    GetPreCompiledQuery()
{
    return db => from cust in db.Customers 
                 where cust.Country == "Germany"
                 select cust;
}

顺便说一句,值得注意的是,对于简单查询,查询表达式通常比使用扩展方法更麻烦。例如,以上内容相当于:

private static Expression<Func<Northwind_LINQtoSQLDataContext,
                               IQueryable<Customer>>
    GetPreCompiledQuery()
{
    return db => db.Customers.Where(cust => cust.Country == "Germany");
}