这会编译,但在运行时会抛出异常。
using (var edmx = new MyEDMX())
{
Expression<Func<SearchResult, int, bool>> pred = (sr, idx) =>
sr.Foo >= searchParams.MinFoo && sr.Foo <= searchParams.MaxFoo
;
return edmx.SearchResults.Where(pred).ToList();
}
例外是System.NotSupportedException
:
LINQ to Entities无法识别方法'System.Linq.IQueryable`1 [MyNamespace.SearchResult] 其中[信息搜索结果(System.Linq.IQueryable`1 [MyNamespace.SearchResult] System.Linq.Expressions.Expression`1 [System.Func`3 [MyNamespace.SearchResult,System.Int32,System.Boolean]])” 方法,并且此方法无法转换为商店表达式。
我认为这个问题与谓词表达式的Int32
参数有关,因为如果我替换下面的谓词,代码在运行时就能完美运行:
Expression<Func<SearchResult, bool>> pred = (sr) =>
sr.Foo >= this.MinFoo && sr.Foo <= this.MaxFoo
;
return edmx.SearchResults.Where(pred).ToList();
如果没有谓词的Int32
参数,则会解析为Queryable<TSource>.Where()
的不同重载。它返回正确的筛选结果,而不会抛出异常。
Int32
版本为Intellisense所知,它为我正在使用的.NET版本编译and it's documented,.NET 4.5。无论表达式是否实际对Int32 idx
参数执行任何操作,我都会得到相同的异常。
通常“LINQ to Entities无法识别方法”意味着您正在调用一个方法,该方法在查询的任何内容中都没有等效 - 在这种情况下是SQL。
LINQ to SQL是否不知道如何在LINQ to SQL查询中创建行号? EDMX正在服务(包装,反映,公开,等等)SQL Server视图。
有没有人猜到这里出了什么问题?
我需要做的任何事情都可以使用Skip / Take来完成,但是我很好奇。
答案 0 :(得分:0)
提供的func需要2个参数,但是只有一个。下面的代码首先在SearchResults上创建一个匿名类型。匿名类型具有搜索结果和索引值。然后我们可以将它传递给IQueryable;
using (var edmx = new MyEDMX())
{
var pred = (sr, idx) =>
sr.Foo >= searchParams.MinFoo && sr.Foo <= searchParams.MaxFoo;
return edmx.SearchResults
.Select((v, i) => new {result = v, index = i})
.Where( w=> pred(w.result, w.index)).ToList();
}