繁体   English   中英

如果我随后在 EF Core 中执行 Select,则对 Include 的过滤将恢复

[英]Filtering on Include reverted if I perform Select afterwards in EF Core

我正在尝试在 EF Core 中使用过滤的包含,但遇到了一个我似乎无法确定具体原因的问题。

我的查询看起来像这样:

context.Users.Include(u=>u.UserRoles.Where(r => r.Role.Category == 3))
             .ThenInclude(r=>r.Role).Where(u => u.userId == currentUserId)
             .Select(u=> new UserDTO()
{
    UserDisplayName= u.Name,
    ListOfRoles = String.Join(",", u.UserRoles.Select(u => u.Role.DisplayName))
}).FirstOrDefaultAsync();

如果我从查询中省略 Select 部分并检查对象,它只填充了适当的 UserRoles,属于类别 3 的用户角色,但在检查此 Select 的结果时,它还包含属于不同的角色类别,连接到 ListOfRoles。

如果有人知道可能导致这种情况的原因,我将不胜感激。

谢谢

Include仅适用于您返回实体的情况。 当您将投影与Select一起使用时,您需要过滤Select表达式中的数据:

context.Users
    .Where(u => u.userId == currentUserId)
    .Select(u=> new UserDTO()
    {
        UserDisplayName= u.Name,
        ListOfRoles = String.Join(",", u.UserRoles
            .Where(ur => ur.Role.Catecory == 3)
            .Select(ur => ur.Role.DisplayName))
    }).SingleOrDefaultAsync();

我相信 String.Join 需要在 EF Core 中进行客户端评估。 这可能会导致加载意外数据。 避免这种情况的建议是在 DTO 内执行串联,以便 Linq 查询加载原始数据并可以有效地将其转换为 SQL:

context.Users
    .Where(u => u.userId == currentUserId)
    .Select(u=> new UserDTO()
    {
        UserDisplayName= u.Name,
        Roles = u.UserRoles
            .Where(ur => ur.Role.Catecory == 3)
            .Select(ur => ur.Role.DisplayName))
            .ToList();
    }).SingleOrDefaultAsync();

在 DTO 中,您将拥有:

[Serializable]
public class UserDTO
{
    public string UserDisplayName { get; set; }
    public IList<string> Roles { get; set; } = new List<string>();
    public string ListOfRoles
    {
        get { return string.Join(",", Roles); }
    }
}

这确保查询可以高效运行并完全转换为 SQL,然后将格式移动到 DTO。

仅当您直接选择实体时, Include才会起作用。 进行投影(例如Select )后, Include被忽略。 您可以尝试在串联部分应用类别过滤:

context.Users
    .Where(u => u.userId == currentUserId)
    .Select(u=> new UserDTO()
    {
        UserDisplayName= u.Name,
        ListOfRoles = String.Join(",", u.UserRoles.Where(r => r.Role.Category == 3).Select(u => u.Role.DisplayName))
    })
    .FirstOrDefaultAsync();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM