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
超出范围
.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
,在这种情况下,grouping
是IGropuing
,它是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
};