Linq GroupBy throws ArgumentOutOfRangeException

本文关键字:ArgumentOutOfRangeException throws GroupBy Linq | 更新日期: 2023-09-27 17:59:10

我有这两个表

Animals           Activities
+----+-------+    +----+------------+----------+------------+
| Id | Name  |    | Id | Activity   | FkAnimal | Date       |
+----+-------+    +----+------------+----------+------------+
| 1  | Cats  |    | 1  | Ball       | 2        | 2015-05-21 |
+----+-------+    +----+------------+----------+------------+
| 2  | Dogs  |    | 2  | Pet        | 2        | 2015-06-07 |
+----+-------+    +----+------------+----------+------------+
| 3  | Birds |    | 3  | Running    | 1        | 2014-11-03 |
+----+-------+    +----+------------+----------+------------+
                  | 4  | Kill a fly | 1        | 2014-08-05 |
                  +----+------------+----------+------------+
                  | 5  | Kill a fly | 3        | 2014-08-05 |
                  +----+------------+----------+------------+

我想要的是这个查询的结果

SELECT Animals.Name, Animals.Id, Activities.Data
FROM Activities
INNER JOIN Animals ON Animals.Id = Activities.Id
GROUP BY Animals.Name, Animals.Data

在实体框架的LINQ中

这是我的尝试:

//My repository is of type IRepository<Activities>
var list = Repository.GetAll().GroupBy(a => a.Animals).Select((grouping,i) => new {
    name = grouping.Key.Name,
    id = grouping.Key.Id,
    data = grouping.ElementAt(i).Data
}).ToList();

不幸的是,ToList()方法生成ArgumentOutOfRangeException,如果我调试lambda,它会显示i超出范围

Linq GroupBy throws ArgumentOutOfRangeException

.Select((grouping,i) =>中的i是组的索引。在您的示例中,.GroupBy(a => a.Animals)将返回一个IGrouping,它本质上只是一个具有Key属性的IEnumerable.GroupBy(a => a.Animals)的结果大致如下(不确定DbContext到底是什么样子):

{[
    {
        Key: Dogs
        GetEnumerator(): [
            {
                Id: 1
                Activity: Ball
                Date: 2015-05-21
            },
            {
                Id: 2
                Activity: Pet
                Date: 2015-06-07
            }
        ]
    },
    {
        Key: Cats
        GetEnumerator(): [
            {
                Id: 3
                Activity: Running
                Date: 2014-11-03
            },
            {
                Id: 4
                Activity: Kill a fly
                Date: 2014-08-05
            }
        ]
    },
    {
        Key: Birds
        GetEnumerator(): [
            {
                Id: 5
                Activity: Kill a fly
                Date: 2014-08-05
            }
        ]
    }
]}

Select方法是在组上迭代,而不是在组中的元素上迭代。因此,在这种情况下,.Select((grouping,i) =>中的i指的是组(有三个组)的索引,而不是组中的元素。在您的选择中,您正在调用data = grouping.ElementAt(i).Data,在这种情况下,groupingIGropuing,它是IEnumerable,因此ElementAt(i)要求当前正在评估的组中的第i个元素。当你得到第三个组时,i将是2,但组中只有一个元素,因此是例外;至少在这个例子中,您的小组可能会以不同的顺序返回,但原理是相同的。

你可能想要这样的东西:

var list = 
    Repository
    .GetAll()
    .GroupBy(a => a.Animals)
    .Select(grouping => new {
        name = grouping.Key.Name,
        id = grouping.Key.Id,
        data = grouping.Select(x => x)
    }).ToList();

是否执行此操作。。。

var res= from act in Repository.GetAll()
       let anm=act.Animals.Single(a=>a.Id=act.FkAnimal)
       select new {
          anm.Id, anm.Name, act.Activity
       };
相关文章:
  • 没有找到相关文章