无法使用Select转换为SQL(x => Func(x))

时间:2010-03-31 22:03:06

标签: c# asp.net linq linq-to-sql

我正在慢慢学习LINQtoSQL的细节,但这让我感到困惑。

以下是我的陈述:

IQueryable<IEvent> events = (from e in db.getEvents()
                            select e).Select(x => SelectEvent(x, null));

SelectEvent的功能可在this answer here中解释。我没有使用.toList()函数,因为我不希望将数千条记录带入内存。

public IEvent SelectEvent(SqlServer.Event ev, EventType? type) {
    // Create an object which implements IEvent
    // I don't have the code in front of me, so forgive the lack of code
}

我的问题实际上是Select()方法。我收到“无法转换为SQL”错误,错误消息中列出了Select()

对此不感兴趣: - /。

3 个答案:

答案 0 :(得分:3)

Linq to SQL无法将任意函数调用转换为SQL。它不知道该功能是做什么的。你必须使用表达式构造SelectEvent所做的任何事情。

或者,如果您要做的只是在查询通过数据库之后将对象映射到其他内容,只需在循环结果时执行此操作,或者创建为您执行此操作的包装生成器。

答案 1 :(得分:3)

它(合理地)抱怨它无法将SelectEvent的调用转换为SQL。

如果你在.AsEnumerable()之前放.Select() C#将在IQueryable Select上使用IEnumerable Select:

interface IEnumerable<T> {
    ...
    // Actually, these are extension methods in Enumerable and Queryable.
    IEnumerable<T> Select<TResult>(Func<T, TResult> selector);
    ...
}

interface IQueryable<T> : IEnumerable<T> {
    ...
    IQueryable<T> Select<TResult>(Expression<Func<T, TResult>> selector);
    ...
    IEnumerable<T> AsEnumerable();
}

IEnumerable<IEvent> events = db.getEvents().AsEnumerable().Select(x => SelectEvent(x, null));

或者,如果您可以立即使用IEvent SelectEvent(SqlServer.Event)重载,因为它无法转换为表达式&lt;&gt;:

IEnumerable<IEvent> events = db.getEvents().Select(SelectEvent);

IEnumerable Select对从源IEnumerable返回的每个项执行一次Func<T, TResult>选择器,IQueryable Select将Expression<Func<T, TResult>>选择器传递给LINQ提供程序 - 在LINQ2SQL的情况下尝试生成等效的SQL。

答案 2 :(得分:2)

这里的问题是,在LinqToSQL中,您的查询首先被转换为表达式树,然后转换为实际运行的SQL代码。表达式树形式中只有一小部分C#代码可以转换为SQL。

在这种情况下,表达式树包括对驻留在当前程序集(SelectEvent)中的方法的调用。转换无法将此方法转换为可在SQL Server中运行的代码,因此会引发错误。

要解决此问题,请尝试将SelectEvent的代码内联到查询表达式中。