我想做一些感觉应该很简单的事情,但结果却让我很头疼。我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()
返回的内容是没有好处的。IQueryable
Select