【问题标题】:Seeking for help for SQL server query to search multiple columns of a table using a combination of keywords寻求帮助 SQL server 查询使用关键字组合搜索表的多个列
【发布时间】:2016-11-10 06:14:03
【问题描述】:

我在构建高效的搜索查询时遇到了噩梦。我正在使用 LINQ。要求如下:

在应用程序中有一个文本狐狸字段,用作快速搜索

我要搜索的表包含三个字段MakeModelExtension

用户可以输入的典型关键字如 Honda Accord XL

根据关键字,数据库应该返回匹配的行,问题就从这里开始了。没有限制输入关键字的顺序来准备短语,即可以输入Accord XL Honda,也可以像XL Accord,也可以只是本田。在示例中,Honda 是 Make,Accord 是 Model,XL 是扩展。

理想情况下,搜索结果应该只提取完美匹配,例如如果输入了 Honda Accord,则不会显示 Honda 的其他车型。但主要问题是我不知道他们会输入什么,我必须使用Contains 运算符查看表格的三个不同列。

这是我尝试过的: 我将短语吐出单词并将它们放在一个数组中 var arr = keyWord.Split(new [] {' '})。下一步我在这些数组元素的循环中构建查询:

foreach (var k in arr)
{
   var item = new Vehicle();
   var arrayItem = k;
   var query = DataContext.Vehicles.Where(v =>v.RealName.Contains(arrayItem)
               || v.Model.Contains(arrayItem)
               || v.Style.Contains(arrayItem)).ToList();
   foreach (var v in query)
   {
     if(!result.Contains(v))
     result.Add(v);
   }
}

return result;

现在,当循环正在执行并匹配 Make 的记录时,它已经用 250 个项目填充了列表。但是,当记录以 CT 作为模型或以 TYL 作为扩展名时,如何删除不需要的项目?如果我知道创建关键字的单词的顺序,那么我可以选择使用一行代码从列表中删除不匹配的 Make、Model 或 Extension 并返回最终结果。但在这种情况下,如果我必须这样做,我再次必须使用循环并删除不匹配的项目,即使这样也可能不会给我正确的数据。这绝对不是执行此操作的有效方法。

【问题讨论】:

  • 如果用户输入了三个单词(假设我们将XL 算作一个单词),您是否只想返回匹配所有三个单词的结果?如果是这样,这听起来像是一个relational division 问题,如果你纯粹在 SQL 中做的话。
  • 您介意再解释一下吗?
  • 这是哪个 SQL 提供程序? (LINQ-to-SQL,实体框架,...)

标签: c# sql-server asp.net-mvc linq


【解决方案1】:

--- 尝试使用下面的方式,您的代码首先检索相应的数据库-----然后过滤获取先前的结果。

List<Vehicle> lsvehicle= new List<Vehicle()>;
foreach (var k in arr)
{
   var arrayItem = k;
   lsvehicle = DataContext.Vehicles.Where(v =>v.RealName.Contains(arrayItem)                ).ToList();
}
foreach (var k in arr)
{
lsvehicle = lsvehicle.Where(v =>v.Model.Contains(arrayItem) || v.Style.Contains(arrayItem)).tolist();
}

return lsvehicle ;

【讨论】:

  • 看起来简单但有效:) 让我试试这个!
【解决方案2】:

这可以通过连接 Make + Model + Extension 字符串,然后比较整个数组是否包含在该字符串中来实现

var query = DataContext.Vehicles;
foreach (var k in arr)
{
   var item = new Vehicle();
   var arrayItem = k;
   query = query.Where(v => (v.RealName + v.Model + v.Style).Contains(arrayItem)).ToList();
}

return query;

注意:逻辑答案,如果有可能需要语法错误纠正

【讨论】:

  • 这看起来更像是评论而不是答案。要获得更好的答案,您可以添加一个示例,更好的是,将原始帖子转换为适合您的示例。
【解决方案3】:

如果您可以选择在数据库中创建视图,我建议您采用以下方法 并且您正在搜索三列

1) 使用所有组合创建视图 2)使用linq从视图中获取记录

sql

create view [Vw_VehicleSearch]
AS
Select       
   M+V+E [MVE],
   M+E+V [MEV],
   V+M+E [VME],
   v+E+M [VEM],
   E+M+V [EMV],
   E+V+M [EVM]
from
   vehicletable

c#

public List<string> Search(string quickSearchText)
{
   using(var ctx=new model()))
   {
       var result=ctx
              .Vw_VehicleSearch
              .Where(v=>v.MVE.Contains(quickSearchText)
               || v=>v.MEV.Contains(quickSearchText)
              .|| v=>v.VME.Contains(quickSearchText)
              .|| v=>v.VEM.Contains(quickSearchText)
              .|| v=>v.EMV.Contains(quickSearchText)
              .|| v=>v.EVM.Contains(quickSearchText)
              .ToList();

        return result.Select(r=>r.MVE).ToList();
   }
 }

【讨论】:

    【解决方案4】:

    您想要的是:RealNameModelStyle 包含所有关键字的所有车辆。这可以通过以下方式实现:

    var query = DataContext.Vehicles.Where(v =>
                       arr.All(s => v.RealName.Contains(s))
                    || arr.All(s => v.Model.Contains(s))
                    || arr.All(s => v.Style.Contains(s)))
               .ToList();
    

    Entity Framework 能够将此查询转换为 SQL,因为它具有将数组 arr 转换为可在 SQL 语句中使用的表(排序)的技巧(您应该查看生成的 SQL )。

    这不是运行查询的最有效方式。当关键字的数量变得“大”时,它会变得相当慢。不过,我认为这不是问题。

    【讨论】:

      猜你喜欢
      • 2021-05-08
      • 2021-04-11
      • 1970-01-01
      • 1970-01-01
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多