C# 如何向Linq查询动态添加Where和Or语句

C# 如何向Linq查询动态添加Where和Or语句,c#,.net,linq,linq-to-sql,C#,.net,Linq,Linq To Sql,第一次使用c#和Linq。我有一根绳子穿过我的路线。我想在两个不同的列中搜索字符串中的值。假设我在一个空格中拆分每个单词,foreach我想动态地向我的linq语句添加一个.Where。我想我可能还需要动态添加一个。或 foreach (string q in query) { results = results.Where(u => u.Name.Contains(r)); results = results.Where(u => u.Text.Contains(r

第一次使用c#和Linq。我有一根绳子穿过我的路线。我想在两个不同的列中搜索字符串中的值。假设我在一个空格中拆分每个单词,
foreach
我想动态地向我的linq语句添加一个
.Where
。我想我可能还需要动态添加一个
。或

foreach (string q in query)
{
    results = results.Where(u => u.Name.Contains(r));
    results = results.Where(u => u.Text.Contains(r));
}
我已经习惯了JS,在这里你可以做一些类似于
results+=results的事情。在这里(…)
我不确定使用linq构造这种东西的合适方法

编辑:为了清晰起见,这里是整个方法

            using (var context = new MessageContext())
        {
            string[] words = query.Split(" ");
            var messages = (from m in context.Messages
                          join u in context.Users on m.UserId equals u.UserID
                          select new
                          {
                              m.Id,
                              m.Date,
                              m.Name,
                              m.Text,
                              m.UserId,
                              u.Image
                          });

            foreach (string word in words)
            {
                messages = messages.Where(u => u.Name.Contains(word)).Union(messages.Where(u => u.Text.Contains(word)));

            return messages.ToList();
        }
或者您可能需要更详细地阐述您的问题

Linq使用惰性计算(在开始迭代结果之前,或者在调用类似ToList()的方法之前,不会计算结果)。正如John指出的,每次连续调用实际上只是修改搜索条件。因此在你的例子中

results = results.Where(u => u.Name.Contains(r));
results = results.Where(u => u.Text.Contains(r));
相当于

results = results.Where(u => u.Name.Contains(r)).Where(u => u.Text.Contains(r));
这意味着一个新的条件。如果你想要一个或一个条件,你需要我们的联合运营商

results = results.Where(u => u.Name.Contains(r)).Union(results.Where(u => u.Text.Contains(r)));
这种延迟计算的好处是,您可以提取一个基本查询并添加额外的搜索条件,从而简化代码


我希望这能有所帮助。

将成为
的一部分,是吗?比如
。其中(x=>x==“a”| | x==“b”)
您可以使用其中一个,也可以使用另一个,但是如何防止它覆盖
结果中已经包含的数据。
@John@ChristopherMellor约翰的例子告诉你怎么做。不要说
results=this
,然后再说
results=that
。只需获得一次结果,然后查找
u.Name.Contains(r)| | u.Text.Contains(r)
。这将生成一个包含所有匹配元素的列表。还有
.addRange()
-任何一种方法都可以,但我选择一次性查询。@Christopher你不是在覆盖,而是在链接
.Where(a=>a.Opt1==true)。Where(a=>a.Opt2=false)
相当于
。Where(a=>a.Opt1==true&&a.Opt2==false)
感谢您的解释——它澄清了很多。然而,Linq似乎没有做你上面提到的懒惰评估,但也许我误用了它。如果你看看上面的编辑,也许你可以提供一些见解?当我调试时,第一次通过
foreach
时,似乎
messages
确实过滤掉了一些消息。下一次通过foreach,它将在已筛选为包含第一项的消息中搜索包含查询中第二项的消息。。。如果这有道理的话。。。
results = results.Where(u => u.Name.Contains(r)).Union(results.Where(u => u.Text.Contains(r)));