我想做一些感觉应该非常简单的事情,但事实证明这是一件非常令人头痛的事情。我是Select
来自IQueryable
,而不是创建一个新对象,我想“调整”我正在投影的那个。这是我想要做的(context
是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();
这很好,因为实体框架不必实际获取与每个事件关联的所有User
实体,并且可以使用聚合COUNT
函数来简单地获取用户数。但是,它不起作用,因为IQueryable
Select
版本的.Select(evnt => evnt)
想要一个没有方法体的lambda语句,可以将其转换为表达式树。因此,虽然上述方法不起作用,但这样做:
.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
,然后再做一个全新的eventsToReturnData
eventsToReturnData
上的IEnumerable
,因为Event
是UnmappedUsersCount
(因此lambda可以有一个方法体),只需通过设置{来调整Event.Users.Count()
对象{1}}我从第一个查询得到的整数。
有更简单或更优雅的方法吗?我想避免EF必须为每个事件检索所有用户,因此仅使用IQueryable
Select
{{1}}方法返回的内容就不行了。
答案 0 :(得分:1)
您可以利用Expression
类在运行时构建一个树,但这样做的工作和代码非常多,只有在您不得不多次执行此类操作时才能证明这一点。
如果此模式只出现一次或很少出现在您的代码中,那么这是您可以做的最好的。