我正在慢慢学习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()
。
对此不感兴趣: - /。
答案 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
的代码内联到查询表达式中。