我写的这个查询失败了,我不知道为什么。
我正在做的是获取用户域对象列表,将它们投影到视图模型,同时计算它们的排名,因为数据将显示在排行榜上。这就是我想要进行查询的方式。
var users = Context.Users.Select(user => new
{
Points = user.UserPoints.Sum(p => p.Point.Value),
User = user
})
.Where(user => user.Points != 0 || user.User.UserId == userId)
.OrderByDescending(user => user.Points)
.Select((model, rank) => new UserScoreModel
{
Points = model.Points,
Country = model.User.Country,
FacebookId = model.User.FacebookUserId,
Name = model.User.FirstName + " " + model.User.LastName,
Position = rank + 1,
UserId = model.User.UserId,
});
return await users.FirstOrDefaultAsync(u => u.UserId == userId);
异常消息
System.NotSupportedException: LINQ to Entities does not recognize the method 'System.Linq.IQueryable`1[WakeSocial.BusinessProcess.Core.Domain.UserScoreModel] Select[<>f__AnonymousType0`2,UserScoreModel](System.Linq.IQueryable`1[<>f__AnonymousType0`2[System.Int32,WakeSocial.BusinessProcess.Core.Domain.User]], System.Linq.Expressions.Expression`1[System.Func`3[<>f__AnonymousType0`2[System.Int32,WakeSocial.BusinessProcess.Core.Domain.User],System.Int32,WakeSocial.BusinessProcess.Core.Domain.UserScoreModel]])' method, and this method cannot be translated into a store expression.
答案 0 :(得分:1)
不幸的是,EF不知道如何翻译带有两个参数(值和等级)的lambda的版本。
对于您的查询,有两种可能的选项:
如果行集非常小,您可以跳过在查询中指定Position,将所有UserScoreModel读入内存(使用ToListAsync),并计算内存中Position的值
如果行集很大,您可以执行以下操作:
var userPoints = Context.Users.Select(user => new
{
Points = user.UserPoints.Sum(p => p.Point.Value),
User = user
})
.Where(user => user.Points != 0 || user.User.UserId == userId);
var users = userPoints.OrderByDescending(user => user.Points)
.Select(model => new UserScoreModel
{
Points = model.Points,
Country = model.User.Country,
FacebookId = model.User.FacebookUserId,
Name = model.User.FirstName + " " + model.User.LastName,
Position = 1 + userPoints.Count(up => up.Points < model.Points),
UserId = model.User.UserId,
});
请注意,这与我编写的内容完全相同,因为两个绑定点总数的用户不会被任意分配不同的等级。如果需要,您可以重写逻辑以断开userId上的联系或其他一些措施。这个查询可能不像你希望的那样漂亮和干净,但是由于你最终只能通过userId选择一行,所以希望它不会太糟糕。您还可以将基本信息的排名和选择拆分为两个单独的查询,这可能会加快速度,因为每个查询都会更简单。