2016-11-23 42 views
0

我有一个搜索表单,它在搜索目录时接受多个单词。当用户搜索每个单词长度大于等于3个字符的术语时,结果将按预期返回。但是,如果一个术语包含3个字符的单词,它将返回更多的结果,这些结果对过滤器要求无效。使用Linq查询返回无效结果的存储库

在我的资源库中,我有下面的代码,其中value传入并且employees是DbSet。

var searchTerms = value.Split(' ') 
       .Select(v => v.Trim().ToLower()) 
       .ToList(); 

var data = this.employees 
       .Where(e => searchTerms.Any(s => e.fname.Contains(s)) || 
        searchTerms.Any(s => e.lname.Contains(s)) || 
        searchTerms.Any(s => e.dept.name.Contains(s)) || 
        e.dept.dept_subs 
         .Where(d => searchTerms 
          .Any(s => d.name.Contains(s))) 
           .Any()) 
       .Where(e => e.isActive == true) 
       .OrderBy(e => e.lname) 
       .ThenBy(e => e.fname) 
       .AsEnumerable(); 

所以问题仍然存在,为什么查询打破两个字符的单词,我该如何解决它?

UPDATE

好。事实证明,它不限于2个字符。

结果格式如下。如果一个子部门是空的,它将只是名字行。

LastName, FirstName 
SubDepartment, Department 

搜索 '阿里' 返回

Adams, Nadiyah 
Logistics, Resources Directorate 

Ahmed, W*ali*ul 

为 'JR'

Brooks, *Jr*, Cecil 
Customer Service Center, Program Administration Directorate 

Brown *Jr*, Peter 
Document Control and Data Management, Operations Directorate 

一个搜索 ''

搜索

更新2

正如意见中的要求,这里有三大类:

public partial class dept 
{ 
    ctor() 
    public string name { get; set; } 
    public virtual ICollection<dept_sub> dept_subs { get; set; } 
    public virtual ICollection<employee> employees { get; set; } 
} 

public partial class dept_sub 
{ 
    ctor() 
    public string name { get; set; } 
    public int dept_id { get; set; }  
    public virtual dept dept { get; set; } 
    public virtual ICollection<employee> employees { get; set; } 
} 

public partial class employee 
{ 
    ctor()  
    public string fname { get; set; } 
    public string lname { get; set; } 
    public Nullable<int> dept_id { get; set; } 
    public Nullable<int> dept_sub_id { get; set; } 
    public virtual dept dept { get; set; } 
    public virtual dept_sub dept_sub { get; set; } 

} 
+1

你有一个样本数据? – Bigeyes

+4

另外,如果'value'在单词之间有多个空格,则最终会在'searchTerms'数组中找到一些空字符串,这将导致所有记录匹配。 – wdosanjos

+0

如果你注意到,Nadiyah和Charles都不应该返回 – Ian

回答

0

@KMoussa和@ ZER0促使我寻找潜在的问题。我还实施了@wdosanjos推荐。

employee对象引用deptdept_sub。而不是去在周围方法与employee要求dept_subdept它的名字,我重新路由查询跳跃指挥链(因为它映射),并调整查询像下面。

我调整了代码如下,它似乎返回更好的结果。

// trim off any whitespace on the ends 
string term = value.Trim(); 

// remove and replace extended spaces with a single space 
RegexOptions options = RegexOptions.None; 
Regex regex = new Regex("[ ]{2,}", options); 
term = regex.Replace(term, " "); 

// break down the property into a collection of strings 
List<string> searchTerms = term.Split(' ') 
    .Select(v => v.Trim().ToLower()) 
    .ToList(); 

// query the dbset 
IEnumerable<employee> data = this.employees 
    .Where(e => searchTerms.Any(s => e.fname.Contains(s)) || 
       searchTerms.Any(s => e.lname.Contains(s)) || 
       searchTerms.Any(s => e.dept.name.Contains(s)) || 
       searchTerms.Any(s => e.dept_sub.name.Contains(s))) // new line 
       // e.dept.dept_subs.Where(d => 
       //  searchTerms.Any(s => d.name.Contains(s))).Any()) 
    .Where(e => e.isActive == true) 
    .OrderBy(e => e.lname) 
    .ThenBy(e => e.fname);