【问题标题】:How to concat IQuerable<T> and List<T>如何连接 IQueryable<T> 和 List<T>
【发布时间】:2019-11-21 20:02:09
【问题描述】:

我有 BaseDocumentTextDocumentExcelDocumentWordDocument 课程。他们继承自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(一个接口)连接起来。与问题无关。

标签: c# entity-framework concat iqueryable


【解决方案1】:

为什么您首先ToListing 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);
}

【讨论】:

  • 我这样做是因为单词集合的类型是列表。我也对此发表评论
  • @DIlshod words 集合的类型是List,因为您很乐意调用ToList。正如我所展示的,这样做没有意义,您的代码示例可以很容易地修复。我不明白你的评论。
  • 试想一下,这句话是 List 集合而不是 IQuerable
猜你喜欢
  • 2011-10-09
  • 2010-11-18
  • 2020-12-22
  • 1970-01-01
  • 1970-01-01
  • 2012-06-23
  • 1970-01-01
  • 2015-07-30
相关资源
最近更新 更多