【问题标题】:In Linq, how do you query based on a child record?在 Linq 中,如何根据子记录进行查询?
【发布时间】:2020-12-08 14:41:33
【问题描述】:

我有一个简单的父/子结构,它存储发送给用户的消息的历史记录。我已经生成了一个 dbContext 并链接了所有实体(使用 EF Core Power Tools)。

那么当 UserID 位于子表(称为 PushNotificationReceipients)中时,我如何才能真正获取某个 UserID 的所有通知?

我以为我可以做这样的事情,但它失败并出现错误:

    var recipient = new PushNotificationRecipient();
    recipient.UserId = userId;
    var results = _dbContext.PushNotifications
        .Include(t => t.PushNotificationContents)
        .Where(t => t.PushNotificationRecipients.Contains(recipient))
        .ToList();

..但这给出了错误

无法翻译 LINQ 表达式。要么以可翻译的形式重写查询,要么通过插入对 AsEnumerable() 的调用显式切换到客户端评估

..而且客户评估太慢了。

有什么办法可以在 Linq 中做到这一点,还是我需要直接传入 SQL?

【问题讨论】:

    标签: c# entity-framework-core linq-to-entities


    【解决方案1】:

    Where 中的表达式存在两个主要问题:

    1. 正如异常消息告诉您的那样,该表达式无法转换为 SQL。

    2. 即使可以将其转换为 SQL,.Contains() 仍然会返回 false。这是因为您创建的新 PushNotificationRecipient 对象与集合中的对象不同。仅仅因为它具有相同的 id 并不能使两个对象相等。

    尝试以下方法:

    var results = _dbContext.PushNotifications
        .Include(t => t.PushNotificationContents)
        .Where(t => t.PushNotificationRecipients.Any(r => r.UserId == userId))
        .ToList();
    

    【讨论】:

    • 我试图使用 PushNotificationRecipients.Where() 但由于某种原因这不是有效的语法。
    • @NickG 如果你想使用Where,你需要.Where(t => t.PushNotificationRecipients.Where(r => r.UserId == userId).Any())。不过,上面的版本更具可读性。
    • 啊,是的,我现在明白了。 Where() 需要布尔结果,因此需要 Any() 而不是嵌套的 Where() (不会导致布尔值)。非常感谢!
    • 没错。 Where() 后面需要跟 .Any() 或 .FirstOrDefault() != null,这是一个更长的版本;)
    【解决方案2】:

    你可以尝试使用ThenInclude,它是用来加载相关数据的

    var recipient = new PushNotificationRecipient();
    recipient.UserId = userId;
    var results = _dbContext.PushNotifications
     .Include(t => t.PushNotificationContents)
     .ThenInclude(t => t.PushNotificationRecipients)
     .Where(notification => notification.<your condition>)
     .ToList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多