从IQueryable <igrouping <int,object =“”>&gt;展平IQueryable到IQueryable <object>

时间:2018-05-25 11:08:56

标签: c# entity-framework linq-to-sql

我在将IQueryable<IGrouping<int, object>>转换为IQueryable<object>时遇到问题。

该对象是一个属性为int Index的类 IGrouping's密钥是该索引 我想得到一个合并的IQueryable<object>,其中只考虑最低的索引。

E.g。

的几个分组
  • IGrouping<3, object>
  • IGrouping<4, object>
  • IGrouping<4, object>
  • IGrouping<5, object>
  • IGrouping<6, object>
  • IGrouping<3, object>
  • IGrouping<3, object>

结果应该是IQueryable<object>,其中只有索引 3 的对象在里面。

P.S我需要一个IQueryable来执行DateTime DbFunctions。所以希望这可以通过一个SQL查询来完成。

4 个答案:

答案 0 :(得分:1)

您可以使用OrderBy对您的群组进行排序,然后使用FirstOrDefault

进行第一组排序
var firstGroup = list.GroupBy(x => x.Index)
  .OrderBy(g => g.Key)
  .FirstOrDefault()
  .AsQueryable();

请参阅example

答案 1 :(得分:1)

要按照描述展平群组,您需要:

  1. 按索引
  2. 对每个组内的对象进行排序
  3. 从每个组中获取第一个顶级对象
  4. 此代码示例演示了LINQ查询:

    IQueryable<MyObject> objects = new[]
    {
        new MyObject{ GroupId = 3, Index = 31, OtherProperty = "Group 3 / Index 31" },
        new MyObject{ GroupId = 3, Index = 32, OtherProperty = "Group 3 / Index 32" },
        new MyObject{ GroupId = 3, Index = 32, OtherProperty = "Group 3 / Index 32" },
        new MyObject{ GroupId = 4, Index = 43, OtherProperty = "Group 4 / Index 43" },
        new MyObject{ GroupId = 4, Index = 42, OtherProperty = "Group 4 / Index 42" },
        new MyObject{ GroupId = 4, Index = 45, OtherProperty = "Group 4 / Index 45" },
        new MyObject{ GroupId = 4, Index = 46, OtherProperty = "Group 4 / Index 46" },
        new MyObject{ GroupId = 5, Index = 51, OtherProperty = "Group 5 / Index 51" },
        new MyObject{ GroupId = 5, Index = 54, OtherProperty = "Group 5 / Index 54" },
        new MyObject{ GroupId = 6, Index = 67, OtherProperty = "Group 6 / Index 67" },
        // ...                                                                    
        new MyObject{ GroupId = 6, Index = 63, OtherProperty = "Group 6 / Index 63" }
    }.AsQueryable();
    
    IQueryable<IGrouping<int, MyObject>> groups = objects.GroupBy(o => o.GroupId);
    
    IQueryable<MyObject> outcome = groups.Select(grouping => grouping.OrderBy(g => g.Index).First());
    
    List<MyObject> outcomeList = outcome.ToList();
    
    // outcomeList contains: 
    // new MyObject{ GroupId = 3, Index = 31, OtherProperty = "Group 3 / Index 31" };
    // new MyObject{ GroupId = 4, Index = 42, OtherProperty = "Group 4 / Index 42" };
    // new MyObject{ GroupId = 5, Index = 51, OtherProperty = "Group 5 / Index 51" };
    // new MyObject{ GroupId = 6, Index = 63, OtherProperty = "Group 6 / Index 63" };
    

答案 2 :(得分:1)

实际上我终于找到了合适的解决方案。 以前答案的问题始终是First()电话。

list.Where(SomeFilterExpression)
    .GroupBy(e => e.Index)
    .OrderBy(g => g.Key)
    .Take(1)
    .SelectMany(g => g.Select(e => e))
    .Where(SomeAdditionalFilterExpression)
    .ToList()

此代码(尤其是Take()帮助我仅使用一个 SQL查询来解决我的问题) 无论如何,谢谢你的专业知识。

答案 3 :(得分:0)

  

的SelectMany

会变平,然后您可以再次按结果排序并按结果排序。但是对于组中的项目返回单个结果集SelectMany就在那里