【问题标题】:Using Linq To SQL to search for multiple strings in a field使用 Linq To SQL 在一个字段中搜索多个字符串
【发布时间】:2010-12-06 17:12:17
【问题描述】:

我正在尝试使用 Linq to SQL 在文本列中搜索多个匹配的单词,但查询没有达到我的预期。

这是我的示例代码:

            string[] nameSearch = new string[2];
            nameSearch[0] = "John";
            nameSearch[1] = "Doe";

            var customers = context.Customers.AsQueryable();
            foreach (string name in nameSearch)
            {
                customers = customers.Where(r => r.CustName.Contains(name));
            }
            Data.Customer[] results = customers.ToArray();

运行的查询是:

    SELECT [t0].[CustName]
    FROM [dbo].[Customer] AS [t0]
    WHERE ([t0].[CustName] LIKE @p0) AND ([t0].[CustName] LIKE @p1)
    -- @p0: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [%Doe%]
    -- @p1: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [%Doe%]

如何解决此查询? (假设是在搜索 John 和 Doe,而不是 Doe 和 Doe。)

【问题讨论】:

    标签: c# linq-to-sql


    【解决方案1】:

    您的 lambda 表达式仅在查询运行时进行评估,即在调用 ToArray() 期间。届时,name 将绑定到数组中的最后一项。

    您可以在 foreach 循环中使用局部变量,以避免在 lambda 表达式中引用外部 name 变量:

    var customers = context.Customers.AsQueryable();
    for (string name in nameSearch) {
        string curName = name;
        customers = customers.Where(r => r.CustName.Contains(curName));
    }
    Data.Customer[] results = customers.ToArray();
    

    【讨论】:

    • 对,你不想捕获循环变量。
    【解决方案2】:

    答案:

    foreach (string name in nameSearch)
    {
        string name_ = name;
        customers = customers.Where(r => r.CustName.Contains(name_));
    }
    

    解释:

    lambda 函数r => r.CustName.Contains(name) 捕获name 变量。相同的变量在两次迭代的范围内。使用块范围临时中断此链接,因此 lambda 函数的每次调用都会选择具有不同值的不同变量。

    【讨论】:

      【解决方案3】:
      string[] nameSearch = new string[2];
      nameSearch[0] = "John";
      nameSearch[1] = "Doe";
      
      
      var result = customers.Where(r => nameSearch.Contains(r.CustName));
      

      【讨论】:

        【解决方案4】:

        不是上面的错,每次都会覆盖客户!

        customers = customers.Where(r => r.CustName.Contains("John") && r.CustName.Contains("Doe"));

        【讨论】:

        • 如果“上述”是指@Frédéric 或我的答案(相同投票的答案是随机排序的),那么不,它们没有错。循环的每一轮都将customers LINQ 表达式替换为一个将Where 子句应用于原始表达式的新表达式。这是一种用于构建复杂查询的相当标准的技术。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-12
        • 1970-01-01
        • 1970-01-01
        • 2018-12-06
        • 1970-01-01
        相关资源
        最近更新 更多