Enumerable.Empty<T>().AsQueryable();此方法支持 LINQ to Entities 基础结构,不打算直接从您的代码中使用
Posted
技术标签:
【中文标题】Enumerable.Empty<T>().AsQueryable();此方法支持 LINQ to Entities 基础结构,不打算直接从您的代码中使用【英文标题】:Enumerable.Empty<T>().AsQueryable(); This method supports the LINQ to Entities infrastructure and is not intended to be used directly from your code 【发布时间】:2016-10-15 09:08:04 【问题描述】:我收到运行时错误
此方法支持 LINQ to Entities 基础架构,不支持 旨在直接从您的代码中使用。
描述:执行过程中发生了未处理的异常 当前的网络请求。请查看堆栈跟踪以获取更多信息 有关错误的信息以及它在代码中的来源。
异常详细信息:System.InvalidOperationException:此方法 支持 LINQ to Entities 基础结构,并非旨在 直接从您的代码中使用。
我正在尝试生成查询,而不是过滤每个搜索条件,而是通过在所有搜索字段上添加所有匹配记录来包含(将使用OR
而不是AND
)。
public static IQueryable<T> ApplySearch<T>(this IQueryable<T> queryable, SearchModel search) where T : class
var results = Enumerable.Empty<T>().AsQueryable();
if (search != null)
if (search.PolicyNumber.HasValue && typeof (IPolicyNumber).IsAssignableFrom(queryable.ElementType))
results = results.Union(queryable.SearchByPolicyNumber(search));
if (search.UniqueId.HasValue && typeof (IUniqueId).IsAssignableFrom(queryable.ElementType))
results = results.Union(queryable.SearchByUniqueId(search));
if (!string.IsNullOrWhiteSpace(search.PostCode) && typeof(IPostCode).IsAssignableFrom(queryable.ElementType))
results = results.Union(queryable.SearchByPostCode(search));
return results;
当我介绍 var results = Enumerable.Empty<T>().AsQueryable();
时,机制开始失效,我需要从空的东西开始。
如何从空集开始,然后在顶部构建 Linq-to-sql 结果?
【问题讨论】:
猜测:queryable.Take(0)
可能会成功。 确切地指出此异常发生的位置可能是个好主意。
@spender 就在 .ToList()
之前
@spender 这个查询将在其他地方实现,即使问题就在这里。它在哪里实现并不重要。他通过确定问题的根源并仅表明这一点,很好地完成了工作。
@spender 在将数据传递给 View 之前被调用的那个,直到那时它都在表达式树中。
【参考方案1】:
您可以通过只合并您拥有的结果来重构代码以不需要空集:
public static IQueryable<T> ApplySearch<T>(this IQueryable<T> queryable, SearchModel search) where T : class
var subQueries = new List<IQueryable<T>>();
if (search != null)
if (search.PolicyNumber.HasValue && typeof (IPolicyNumber).IsAssignableFrom(queryable.ElementType))
subQueries.Add(queryable.SearchByPolicyNumber(search));
if (search.UniqueId.HasValue && typeof (IUniqueId).IsAssignableFrom(queryable.ElementType))
subQueries.Add(queryable.SearchByUniqueId(search));
if (!string.IsNullOrWhiteSpace(search.PostCode) && typeof(IPostCode).IsAssignableFrom(queryable.ElementType))
subQueries.Add(queryable.SearchByPostCode(search));
return subQueries.DefaultIfEmpty(queryable)
.Aggregate((a, b) => a.Union(b));
【讨论】:
嗨服务。当我看到名单被介绍时——我就像“他在想什么!一个名单!”?但后来我意识到你做了什么,我必须说 - 这太棒了...... :) 谢谢。 @IvanStoev 您可以添加DefaultIfEmpty
来定义行为。如果它甚至是受支持的情况,这将取决于规格想要它是什么。我最初的怀疑是它想使用queryable
作为默认值。
@IvanStoev 在我的情况下我返回了return subQueries.Any() ? subQueries.Aggregate((a, b) => a.Union(b)) : queryable;
我的表中有一个 XML 列,因此由于 Union 试图在幕后“区分”(据我所知),我最终使用了 Concat:'code' if (subQueries.Count > 0) var finalQuery = subQueries.DefaultIfEmpty().Aggregate((resultQuery, addedQuery) => resultQuery.Concat(addedQuery));返回最终查询; else return Enumerable.Empty我使用过的临时 hack
是变化自
var results = Enumerable.Empty<T>().AsQueryable();
到
var results = queryable.Where(o => false);
【讨论】:
但据我了解,更改会很昂贵,因为它会针对每条记录运行。以上是关于Enumerable.Empty<T>().AsQueryable();此方法支持 LINQ to Entities 基础结构,不打算直接从您的代码中使用的主要内容,如果未能解决你的问题,请参考以下文章
Enumerable.Empty<T>().AsQueryable();此方法支持 LINQ to Entities 基础结构,不打算直接从您的代码中使用