【问题标题】:Adding N conditions to a LINQ query?向 LINQ 查询添加 N 个条件?
【发布时间】:2019-10-17 14:24:02
【问题描述】:

我正在尝试优化以下例程,使其仅使用一个数据库查询而不是多个,但过滤器(循环条件)似乎并未应用,因为所有消息都已获取。

     public async Task<List<Message>> GetInboxMessegesFromUser(string inboxUser, List<string> senders)
     {
             // Doesn't work

            var query = from m in _context.Messeges where m.ToUser == inboxUser select m;
            foreach (string sender in senders)
            {
                query.Where(m => m.FromUser == sender);
            }
            return await query.ToListAsync();

            // Old code 

            List<Message> messeges = new List<Message>();
            foreach (string sender in senders)
            {
                messeges.AddRange(await _context.Messeges.Where(m => m.FromUser == sender && m.ToUser == inboxUser).ToListAsync());
            }


               return messeges;
            }

如何在执行之前向 LINQ 查询添加动态数量的条件,以便 O(N*M) 变为 O(N)?

【问题讨论】:

  • 替换:query = query.Where(m =&gt; m.FromUser == sender);
  • 另外,这在您的场景中会比 foreach 更有效:stackoverflow.com/questions/10667675/…
  • 即使在分配query = query.Where(....); 之后,由于逻辑错误,该查询也不会产生任何结果。您不能在属性上拥有超过 1 个值的记录。因此,如果您在 senders 列表中传入 2 个值,则任何一条记录都不会是这两个值。结果是这个方法总是返回一个空列表。

标签: c# linq


【解决方案1】:

即使在您完成分配query = query.Where(....); 之后,由于逻辑错误,该查询也不会产生任何结果。您不能有一个属性值超过 1 个的记录。因此,如果您在 senders 列表中传入 2 个值,则任何一条记录都不会是这两个值。结果是这个方法总是返回一个空列表。

您可以使用.Contains 查看列表中是否至少有一个匹配项可以转换为 Sql Server 中的 IN 子句。

你的整个方法可以这样重写:

public Task<List<Message>> GetInboxMessegesFromUser(string inboxUser, List<string> senders)
{
    return _context.Messeges
        .Where(message => message.ToUser == inboxUser && senders.Contains(message.FromUser))
        .ToListAsync();
}

【讨论】:

  • 这是正确的,但我很难容忍使用下划线作为变量名。
  • 详细说明:无论如何,下划线可以说是一个糟糕的变量名,但在 C# 7 中,Discards 强化了下划线是您实际上不打算使用的东西的占位符的概念。见docs.microsoft.com/en-us/dotnet/csharp/discards
【解决方案2】:

尝试将现有代码更改为:

messeges.AddRange(await _context.Messeges.Where(m => senders.Contains(m.FromUser) && m.ToUser == inboxUser).ToListAsync());

【讨论】:

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