我试图实施一个非常基本的关键字的搜索中的应用程序使用皇宫-对-sql。我的搜索词在一系列的串,每个阵列项目是一个字,我想找到的行含有搜索词。我不介意,如果它们包含的不仅仅是搜索方面(最有可能的,他们会),但所有的搜索词有待明。

理想情况下,我想类似的东西的片段如下,但我知道这不会的工作。此外,我有看 这个问题在这里, 但提交人的这个问题似乎要做的事情,另一方面( query.Contains(part.partName) ),这并不会为我工作。

public IQueryable<Part> SearchForParts(string[] query)
{
    return from part in db.Parts
           where part.partName.Contains(query)
           select part;
}

我如何可以改写这个的查询,以便它将做什么,我需要什么?

有帮助吗?

解决方案

看在其他试图令我非常难过:(

public IQueryable<Part> SearchForParts(string[] query)
{
  var q = db.Parts.AsQueryable(); 

  foreach (var qs in query)
  { 
    var likestr = string.Format("%{0}%", qs);
    q = q.Where(x => SqlMethods.Like(x.partName, likestr));
  }

  return q;
}

假设:

  • partName看起来像:"ABC123XYZ"

  • 查询是{,"ABC","123","x-y"}

其他提示

一个更简单和更正确的解决办法(然后leppie的):

public IQueryable<Part> SearchForParts(string[] query)
{
    var q = db.Parts.AsQueryable(); 

    foreach (string qs in query)
    {
        q = q.Where(x => x.partName.Contains(qs));
    }

    return q;
}

这将工作,只要 partName 是串(或SQL相当于一个string)。

重要的是要注意的是 partName.Contains(qs) 是不同于 query.Contains(partName).
partName.Contains(qs), partName 是搜查的任何发生的 qs.所得SQL会是同等的(其中 <qs> 是的价值 qs):

select * from Parts where partName like '%<qs>%';

还值得注意的是 StartsWithEndsWith 这是类似于 Contains 但是寻找的串在的具体位置。

query.Contains(partName) 是同一个SQL in 命令。所得SQL将相当于(在那里 <query0> 是的价值 query[0], <query1> 是的价值 query[1], , <queryN> 是的最后一个值在查询阵列):

select * from Parts where partName in ( <query0>, <query1>, ..., <queryN> );

更新:
它也是重要的是要注意,leppie的答案不逃生的通配符之前添加他们的 喜欢 发言。这不是一个问题 Contains 解决方案,因为皇宫会逃跑的查询之前发送。一个逃脱的版本 SqlMethods.Like 解决方案将是:

public IQueryable<Part> SearchForParts(string[] query)
{
    var q = db.Parts.AsQueryable(); 

    foreach (var qs in query)
    {
        string escaped_bs = qs.Replace("/", "//"),
            escaped_us = escaped_bs.Replace("_", "/_"),
            escaped_p = escaped_us.Replace("%", "/%"),
            escaped_br = escaped_p.Replace("[", "/["),
            likestr = string.Format("%{0}%", escaped_br);

        q = q.Where(x => SqlMethods.Like(x.partName, likestr, '/'));
    }

    return q;
}

你不必担心',因为皇宫会逃跑你。

您可以尝试:

public IQueryable<Part> SearchForParts(string[] query)
{
    return from part in db.Parts
           where query.All(term => part.partName.Contains(term))
           select part;
}

不过,我不知道的LINQ to SQL将能够将其转化为T-SQL。另一种选择是:

public IQueryable<Part> SearchForParts(string[] query)
{
    var result = from part in db.Parts
                 select part;

    foreach(var term in query)
    {
        result = from part in result
                 where part.partName.Contains(term)
                 select part;
    }

    return result;
}

这并不漂亮,但它应该工作。你会得到一个查询在where子句。

很多ANDs的

可以写为这

var result = db.Parts.Where(p => query.All(q => p.partName.Contains(q)));

使用 NinjaNye.SearchExtension NuGet包,可以执行轻松此搜索:

string[] terms = new[]{"search", "term", "collection"};
var result = db.Parts.Search(terms, p => p.PartName);

您还可以搜索多个字符串属性

var result = db.Parts.Search(terms, p => p.PartName, p.PartDescription);

或执行RankedSearch返回IQueryable<IRanked<T>>它简单地包括属性示出的检索词显示了多少次:

//Perform search and rank results by the most hits
var result = db.Parts.RankedSearch(terms, p => p.PartName, p.PartDescription)
                     .OrderByDescending(r = r.Hits);

上有项目的更广泛指导GitHub的页面: https://github.com/ninjanye/SearchExtensions

希望这有助于未来的游客

我觉得这有点简单,为我工作:

string[] product = products.Split(','); 
using (var context = new ProjectTrackerEntities()) 
{ var result = from part in context.DBAudits where product.Contains(part.TableName) select part; }

请尝试这样:

public IQueryable<Part> SearchForParts(string[] query)
{
    return from part in db.Parts
           where Search(part.Name,query)
           select part;
}

public bool Search(string partName,string[] query)
{
    for (int i = 0; i < query.Length; i++)
    {
        if(partName.Contains(query[i]))
           return true;
    }

    return false;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top