代码之家  ›  专栏  ›  技术社区  ›  monty

实体框架核心:将多个结果对象组合为一个集合

  •  0
  • monty  · 技术社区  · 8 年前

    我将面对实体框架核心(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实例,这些实例是被引用的accros~10个不同的表。

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

    我是否可以以及如何重写查询以不返回匿名对象,而只返回包含所有值的IEnumerable?

    出于某种原因,编译器不会让我迭代匿名集合并手动将其扁平化。

    2 回复  |  直到 8 年前
        1
  •  1
  •   Derpy    8 年前

    如果您希望每个t1e行有一个数组,那么应该使用这个技巧。

          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();
    
        2
  •  0
  •   RickardN    8 年前

    Add 和/或 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();