Entity Framework 核心:将多个结果对象组合成一个集合

Entity Framework Core: combining multiple result objects into one collection

我正面临 entity framework 核心 (2.0) 的 linq 查询。

  var result = await dbContext.Table1DbSet
.Where(t1e => t1e.Id == id && t1e.Id2 == id2)
.Select
(
  t1e =>
  t1e.Table2NavPropICollection.Select
  (
    t2e => new
    {
      singleObject = t2e.Table3NavPropObject.TargetObject,
      enumerable1  = t2e.Table3NavPropObject.Table4NavPropObject.Table5NavPropICollection.Select(t5e => t5e.TargetObject),
      enumerable2  = t2e.Table3NavPropObject.Table6NavPropObject.Table7NavPropICollection.Select(t7e => t7e.TargetObject),
      enumerable3  = t2e.Table3NavPropObject.Table8NavPropICollection.SelectMany(t8e => t8e.Table9NavPropICollection.Select(t9e => t9e.TargetObject))
    }
  )
)
.ToListAsync();

目标是查询 TargetObject 的所有引用实例,这些实例引用了大约 10 个不同的表。

目前它return是一个 IEnumerable,其中匿名对象包含属性 singleObject、enumerable1、enumerable2、enumerable3。所有这些属性都是 TargetObject 或 IEnumerable 类型。

我能否以及如何将查询重写为不是 return 匿名对象,而是仅包含所有值的 IEnumerable?

出于某种原因,编译器不允许我迭代匿名集合并手动将其展平。

Add and/or Concat 是可行的解决方案吗?

PoC:

var a = new [] { 1,2,3 };

var result = new {
    firstA = a.First(),
    otherAs = a,
    backwards = a.Reverse()
};

var final = new List<int>();
final.Add(result.firstA);
final.Concat(result.otherAs.Concat(result.backwards))
    .Dump();

如果您希望每行一个数组,这应该可以解决问题。

      var result = await dbContext.Table1DbSet
    .Where(t1e => t1e.Id == id && t1e.Id2 == id2)
    .Select
    (
      t1e =>
      t1e.Table2NavPropICollection.Select
      (
        t2e => new[] {t2e.Table3NavPropObject.TargetObject}.Concat(
            t2e.Table3NavPropObject.Table4NavPropObject.Table5NavPropICollection.Select(t5e => t5e.TargetObject)).Concat(
            t2e.Table3NavPropObject.Table6NavPropObject.Table7NavPropICollection.Select(t7e => t7e.TargetObject)).Concat(
            t2e.Table3NavPropObject.Table8NavPropICollection.SelectMany(t8e => t8e.Table9NavPropICollection.Select(t9e => t9e.TargetObject)))
      )
    )
    .ToListAsync();

如果您希望它完全平坦,您需要将 Select 切换为 SelectMany()。

      var result = await dbContext.Table1DbSet
    .Where(t1e => t1e.Id == id && t1e.Id2 == id2)
    .SelectMany
    (
      t1e =>
      t1e.Table2NavPropICollection.Select
      (
        t2e => new[] {t2e.Table3NavPropObject.TargetObject}.Concat(
            t2e.Table3NavPropObject.Table4NavPropObject.Table5NavPropICollection.Select(t5e => t5e.TargetObject)).Concat(
            t2e.Table3NavPropObject.Table6NavPropObject.Table7NavPropICollection.Select(t7e => t7e.TargetObject)).Concat(
            t2e.Table3NavPropObject.Table8NavPropICollection.SelectMany(t8e => t8e.Table9NavPropICollection.Select(t9e => t9e.TargetObject)))
      )
    )
    .ToListAsync();