answer by gnud提出了正確的想法,但不幸的是,兩個提供的解決方案都不能很好地轉化爲SQL。這是因爲EF6查詢翻譯對您編寫LINQ查詢的方式仍然很敏感(不幸的是)。
這裏是產生一個好的翻譯的實現(通過實驗發現)(改decimal?
投給可空類型的Points
屬性類型 - 需要投以避免NRE的情況下設置爲空):
public static async Task<int> GetUsersRank(DbEntities db, string userId)
{
var userPoints = await db.UserIqAnswers
.Where(x => x.UserId == userId && x.IqQuestion.CorrectAnswer == x.Answer)
.SumAsync(x => (decimal?)x.IqQuestion.Points) ?? 0;
var rank = await db.UserIqAnswers
.Select(x => new { x.UserId, x.Answer, x.IqQuestion })
.Where(x => x.UserId != userId && x.IqQuestion.CorrectAnswer == x.Answer)
.GroupBy(x => x.UserId)
.Select(x => new { userId = x.Key, points = x.Sum(y => y.IqQuestion.Points) })
.CountAsync(x => x.points < userPoints || (x.points == userPoints && string.Compare(x.userId, userId) < 0));
return rank;
}
其產生2個SQLS這樣的:
SELECT
[GroupBy1].[A1] AS [C1]
FROM (SELECT
SUM([Extent2].[Points]) AS [A1]
FROM [dbo].[UserIqAnswers] AS [Extent1]
INNER JOIN [dbo].[IqQuestions] AS [Extent2] ON ([Extent1].[Answer] = [Extent2].[CorrectAnswer]) AND ([Extent1].[IqQuestion_Id] = [Extent2].[Id])
WHERE [Extent1].[UserId] = @p__linq__0
) AS [GroupBy1]
和
SELECT
[GroupBy2].[A1] AS [C1]
FROM (SELECT
COUNT(1) AS [A1]
FROM (SELECT
[Extent1].[UserId] AS [K1],
SUM([Extent2].[Points]) AS [A1]
FROM [dbo].[UserIqAnswers] AS [Extent1]
INNER JOIN [dbo].[IqQuestions] AS [Extent2] ON ([Extent1].[IqQuestion_Id] = [Extent2].[Id]) AND ([Extent2].[CorrectAnswer] = [Extent1].[Answer])
WHERE [Extent1].[UserId] <> @p__linq__0
GROUP BY [Extent1].[UserId]
) AS [GroupBy1]
WHERE ([GroupBy1].[A1] < @p__linq__1) OR (([GroupBy1].[A1] = @p__linq__2) AND ([GroupBy1].[K1] < @p__linq__3))
) AS [GroupBy2]
這不會幫助你找到元素的位置。這隻會幫助你,如果你已經知道你想要的元素的位置。 – gnud
@gnud你說得對,我理解了這個問題。 –