如何连接 IQueryable<T> 和 List<T>
Posted
技术标签:
【中文标题】如何连接 IQueryable<T> 和 List<T>【英文标题】:How to concat IQuerable<T> and List<T> 【发布时间】:2019-11-21 20:02:09 【问题描述】:我有 BaseDocument
、TextDocument
、ExcelDocument
和 WordDocument
课程。他们继承自BaseDocument
。我有每个类的集合。假设BaseDocuments
集合从某些地方的某些子实体集合中获取价值。集合类型不同,其中一些是 List,另一种是 IQuerable
和另一种特定类型。 BaseDocuments
集合是 IQuerable
类型并从某些子实体集合中获取值。它看起来像这样:
using (Context context = new Context())
var words = context.GetEntities<BaseDocument>().Where(e => e.Name.StartsWith("Word")).ToList(); // type of collection is list
var excels = context.GetEntities<BaseDocument>().Where(e => e.Name.StartsWith("Excel"));
var texts = context.GetEntities<BaseDocument>().Where(e => e.Name.StartsWith("Text"));
var wordsAsQuery = words.AsQueryable();
baseDocuments = wordsAsQuery.Concat(excels).Concat(texts);
如您所见,我正在使用 Concat 方法。但是当我做var instaces = baseDocuments.ToList();
时,它会抛出异常:
System.InvalidOperationException: '此方法支持 LINQ 实体基础设施,不打算直接从 你的代码。'
我做了一些研究,每次修复代码后,我都会遇到另一个异常,例如
LINQ 错误 DbUnionAllExpression 需要兼容的参数 集合 ResultTypes。
我可以对所有子集合进行 ToList,但这没有意义,而且会出现性能问题。
如何将不同类型的集合连接到 IQuerable 集合?可能吗?
更多关于model的信息可以看我最后一个问题:Loading instance of entity takes more than 1 second
【问题讨论】:
为什么不直接打电话给context.BaseDocuments.Where( condition || condition || condition).ToList()
?
AsQueryable
很少有用。删除它。
@TheGeneral,因为 condition1,condition2 ... 用在不同的地方,在子集合中,我们不知道。我们知道只有子集合和基础集合从中获得价值
如果您能提供minimal reproducible example 这样我们就可以重现该问题,那就太好了。 minimal reproducible example 必须包含所需的一切(包括GetEntities
)。
@KanisXXX 您的解释确实具有误导性。使用 LINQ to Objects 时,您可以轻松地将List
(一个类)与任何IEnumerable
(一个接口)连接起来。与问题无关。
【参考方案1】:
为什么您首先ToList
ing Word 文档,然后对它们执行AsQueryable
?您正在导致 LINQ 忘记有关数据库结构的所有内容并处理内存中的 word
集合。然后,当您使用实际查询将其告知Concat
时,您会得到您指定的错误。为什么不只是:
using (Context context = new Context())
var words = context.GetEntities<BaseDocument>().Where(e => e.Name.StartsWith("Word"));
var excels = context.GetEntities<BaseDocument>().Where(e => e.Name.StartsWith("Excel"));
var texts = context.GetEntities<BaseDocument>().Where(e => e.Name.StartsWith("Text"));
baseDocuments = words.Concat(excels).Concat(texts);
【讨论】:
我这样做是因为单词集合的类型是列表。我也对此发表评论 @DIlshodwords
集合的类型是List
,因为您很乐意调用ToList
。正如我所展示的,这样做没有意义,您的代码示例可以很容易地修复。我不明白你的评论。
试想一下,这句话是 List 集合而不是 IQuerable以上是关于如何连接 IQueryable<T> 和 List<T>的主要内容,如果未能解决你的问题,请参考以下文章
如何检查 IQueryable<T>.Element 类型是不是为接口
如何将 IEnumerable<t> 或 IQueryable<t> 转换为 EntitySet<t>?
如何将 ODataQueryOptions<T> 应用于 IQueryable<X>
如何将 Kendo UI Grid 与 ToDataSourceResult()、IQueryable<T>、ViewModel 和 AutoMapper 一起使用?
在 WebAPI 中使用 OData 时如何将 SelectExpandQueryOption 转换为 IQueryable<T>?