【发布时间】:2022-01-25 19:18:15
【问题描述】:
我不明白如何简化这个请求
var dialogs = await dbContext.UsersDialogs
.AsNoTracking()
.Where(x => x.UserId == userId)
.Select(x => new DialogModel
{
Id = x.DialogId,
Login = x.Dialog.Name,
Image = x.User.FacialImage,
IsConfirm = x.Dialog.Messages.OrderBy(x => x.DateCreate).LastOrDefault().IsRead,
DateTime = x.Dialog.Messages.OrderBy(x => x.DateCreate).LastOrDefault().DateCreate,
LastMessage = x.Dialog.Messages.OrderBy(x => x.DateCreate).LastOrDefault().Content,
LastUserId = x.Dialog.Messages.OrderBy(x => x.DateCreate).LastOrDefault().UserId
})
.ToListAsync();
它将它转换成这样的请求
SELECT [u].[DialogId] AS [Id], [d].[Name] AS [Login], [u0].[FacialImage] AS [Image], (
SELECT TOP(1) [m].[IsRead]
FROM [Messages] AS [m]
WHERE [d].[Id] = [m].[DialogId]
ORDER BY [m].[DateCreate] DESC) AS [IsConfirm], (
SELECT TOP(1) [m0].[DateCreate]
FROM [Messages] AS [m0]
WHERE [d].[Id] = [m0].[DialogId]
ORDER BY [m0].[DateCreate] DESC) AS [DateTime], (
SELECT TOP(1) [m1].[Content]
FROM [Messages] AS [m1]
WHERE [d].[Id] = [m1].[DialogId]
ORDER BY [m1].[DateCreate] DESC) AS [LastMessage], (
SELECT TOP(1) [m2].[UserId]
FROM [Messages] AS [m2]
WHERE [d].[Id] = [m2].[DialogId]
ORDER BY [m2].[DateCreate] DESC) AS [LastUserId]
FROM [UsersDialogs] AS [u]
INNER JOIN [Dialogs] AS [d] ON [u].[DialogId] = [d].[Id]
INNER JOIN [Users] AS [u0] ON [u].[UserId] = [u0].[Id]
WHERE [u].[UserId] = @__userId_0
我以某种方式优化它?我不想使用 SQL 查询,因为 Linq 对我来说似乎更方便。
【问题讨论】:
-
在第一次选择中,可以创建一个匿名对象来存储
x.Dialog.Messages.OrderBy(x => x.DateCreate).LastOrDefault() and other direct property of x,稍后在选择中创建DialogModel的对象。这应该比您多次生成Messages表的查询更好。 -
如果您使用的是 EF Core 5+,这对于 Filtered includes 来说似乎是一个很好的用例
-
TBH 我比我更喜欢 Svyatoslav 的第二种选择。随意将其标记为已接受。
标签: c# linq asp.net-core entity-framework-core