我想做一些感觉应该很简单的事情,但结果却让我很头疼。我Select来自一个IQueryable而不是创建一个新对象,我想“调整”我正在投影的那个。这是我想要做的(context是 a DbContext,我使用的是代码优先方法):
var eventsToReturn =
((IQueryable<Event>)
context.Events
.OrderByDescending(evnt => evnt.TakesPlaceOn)
.Skip(startAt)
.Take(numberToReturn)
)
.Select(evnt =>
{
evnt.UnmappedUsersCount = evnt.Users.Count();
return evnt;
}
)
.ToList();
这很好,因为 Entity Framework 不必实际获取User与每个事件关联的所有实体,并且可以使用聚合COUNT函数来简单地获取用户数量。但是,它不起作用,因为该IQueryable版本需要Select一个没有方法体的 lambda 语句,可以转换为表达式树。因此,虽然上述方法不起作用,但它确实:
.Select(evnt => evnt)
...所以这样做:
.Select(evnt => evnt.Users.Count())
我已经解决了这个问题,但我的方式似乎相当冗长。这是我的方法:
var eventsToReturnData =
((IQueryable<Event>)
context.Events
.OrderByDescending(evnt => evnt.TakesPlaceOn)
.Skip(startAt)
.Take(numberToReturn)
)
.Select(evnt =>
new {
Event = evnt,
UnmappedUsersCount = evnt.Users.Count()
}
)
.ToList();
var eventsToReturn = eventsToReturnData
.Select(evntData => {
evntData.Event.UnmappedUsersCount = evntData.UnmappedUsersCount;
return evntData.Event;
})
.ToList();
所以我将主要Event对象投影到一个匿名对象中,以及int我想添加到它的一个微小对象,然后做一个全新Select的 on eventsToReturnData,这一次工作,因为eventsToReturnData是一个IEnumerable(所以 lambda 可以有一个方法body),只是通过设置我从第一个查询中获得的整数来调整Event对象。UnmappedUsersCount
有没有更简单或更优雅的方法来做到这一点?我想避免 EF 必须为每个事件检索所有用户,因此仅使用's方法Event.Users.Count()返回的内容是没有好处的。IQueryableSelect