entity-framework - EF Core 过滤包含与选择
问题描述
对不起我的英语不好。
当同时使用过滤包含和选择时,我遇到了 EF Core 5.0.9 的错误,我不知道是错误还是功能。:)
return await _dbContext.User
.Where(u => !u.TOROLT)
.Where(u => ids.Contains(u.Id))
.Include(u => u.EventUsers.Where(eu => !eu.TOROLT && eu.EventId == eventId))
.Select(u => new UserDropDownDtoWithInviteData
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
EventUserId = u.EventUsers.First().Id,
IsCelebrated = u.EventUsers.First().IsCelebrated,
IsEventAdmin = u.EventUsers.First().IsEventAdmin,
IsInviteAccepted = u.EventUsers.First().IsInviteAccepted,
IsInvited = u.EventUsers.First().IsInvited,
})
.ToListAsync();
在这个时候,第一个元素不是从过滤的包含中选择的,只是从正常的包含中选择的。来自 Profiler 的 SQL 脚本:
SELECT
[u].[Id],
[u].[FirstName],
[u].[LastName],
(
SELECT TOP(1) [e].[Id]
FROM [dbo].[EventUser] AS [e]
WHERE [u].[Id] = [e].[UserId]) AS [EventUserId],
(
SELECT TOP(1) [e0].[IsCelebrated]
FROM [dbo].[EventUser] AS [e0]
WHERE [u].[Id] = [e0].[UserId]) AS [IsCelebrated],
(
SELECT TOP(1) [e1].[IsEventAdmin]
FROM [dbo].[EventUser] AS [e1]
WHERE [u].[Id] = [e1].[UserId]) AS [IsEventAdmin],
(
SELECT TOP(1) [e2].[IsInviteAccepted]
FROM [dbo].[EventUser] AS [e2]
WHERE [u].[Id] = [e2].[UserId]) AS [IsInviteAccepted],
(
SELECT TOP(1) [e3].[IsInvited]
FROM [dbo].[EventUser] AS [e3]
WHERE [u].[Id] = [e3].[UserId]) AS [IsInvited]
FROM [dbo].[User] AS [u]
WHERE ([u].[TOROLT] <> CAST(1 AS bit))
AND [u].[Id] IN (2, 1, 3, 4, 5)
但是如果是单独的过滤包含和选择,那么它工作得很好,但是这个选择完整的记录而不是他从数据库中的一部分:
var a = await _dbContext.User
.Where(u => !u.TOROLT)
.Where(u => ids.Contains(u.Id))
.Include(u => u.EventUsers.Where(eu => !eu.TOROLT && eu.EventId == eventId))
.ToListAsync();
return a.Select(u => new UserDropDownDtoWithInviteData
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
EventUserId = u.EventUsers.First().Id,
IsCelebrated = u.EventUsers.First().IsCelebrated,
IsEventAdmin = u.EventUsers.First().IsEventAdmin,
IsInviteAccepted = u.EventUsers.First().IsInviteAccepted,
IsInvited = u.EventUsers.First().IsInvited,
})
.ToList();
知道为什么会这样,我该如何解决?
谢谢
解决方案
Include
如果您有自定义投影Select
,则将被完全忽略,因此您的过滤器也将被忽略。这不是错误,Include
仅当您从查询中获取整个实体时才有效。
无论如何考虑重写您的查询:
var query =
from u in _dbContext.User
where !u.TOROLT && ids.Contains(u.Id)
from eu in u.EventUsers.Where(eu => !eu.TOROLT && eu.EventId == eventId)
.Take(1)
.DefaultIfEmpty()
select new UserDropDownDtoWithInviteData
{
Id = u.Id,
FirstName = u.FirstName,
LastName = u.LastName,
EventUserId = eu.Id,
IsCelebrated = eu.IsCelebrated,
IsEventAdmin = eu.IsEventAdmin,
IsInviteAccepted = eu.IsInviteAccepted,
IsInvited = eu.IsInvited,
};
var result = await query.ToListAsync();
推荐阅读
- php - 有谁知道为什么我的 mysql 表没有更新?
- ios - Swift4 中的正则表达式来验证全名
- python - 使用 AWS 放大时出现 502 网关错误,cloudwatch 在随机线路上给出错误?
- java - 为来自子类的基类日志消息添加前缀
- mysql - 如何获取用户订购的最早订单的日期?
- python - Python 'tuple' 无法转换为 MySQL 类型
- css - React CSS 不会显示在移动设备(Chrome、Safari、Firefox)上,但会显示在桌面站点上
- elasticsearch - Elasticsearch - 将符号视为常规字符串并使文本不区分大小写
- winapi - 关于在上下文菜单上获取键盘敲击的问题
- c# - 访问 AzureKeyVault