2017-02-02 51 views
-1

我设法开发了我的第一个具有CRUD功能的MVC 5 Web应用程序。LINQ包含奇怪的行为

我的数据有很少的方式来搜索记录,但其中一个似乎没有做我所期望的。这里是我的控制器搜索查询代码:

query = query.Where(c => 
     c.PostCode.Contains(searchString) 
     || c.Place1.Select(e => e.PostCode).Contains(searchString) 

这里是我的模型:

public Place() 
    { 
     Place1 = new HashSet<Place>(); 
    } 

    [Display(Name = "Postcode")] 
    public string PostCode { get; set; } 

    public virtual ICollection<Place> Place1 { get; set; } 

我的数据库的关系是自引用表 - > 1比0,对于域,因此相同的名称。

任何人都可以解释为什么搜索功能会在为代码的两部分搜索完整值“NR32 4TW”时带来预期结果,但只有搜索的第一个查询部分(Before OR运算符)会找到如果我使用“NR32 4T”进行部分搜索,是否也有同样的记录?

我检查了数据库中的其他字段的查询,他们有同样的问题。

TDLR; LINQ“.Contains()”在模型中的集合上使用它时不搜索字符串的各个部分。有谁能解释这种行为吗?

+1

LINQ是一个接口。你在使用实体框架吗?这是实现LINQ接口的原因。 –

+0

您正将'Enumerable.Contains'与'string.Contains'混合使用。第二个标准应该是'c.Practice1.Any(e => e.PostCode。包含(搜索字符串))'。 –

回答

5

完全没有考虑到,你有一个差异帐户.... Practice1和PLACE1 您正在使用2种不同功能的名称

“包含”

c.PostCode.Contains(searchString) 

这是String.Contains(string) ..它寻找你所称的字符串中的参数...

c.Practice1.Select(e => e.PostCode).Contains(searchString) 

这是IEnumerable<string>.Contains(string) ......它会在字符串枚举的字符串...

你想要做什么是最有可能的:

c.PostCode.Contains(searchString) || c.Practice1.Any(e => e.PostCode.Contains(searchString)) 
+0

我已经调整了代码在第一行反映你的评论。很好的答案,谢谢! – Newseek

1

Enumerable.Contains()正在搜索一个序列(列表),看看是否有确切的值。它不是搜索文本。

+0

PostCode是一个字符串。如果它的EF然后Contains调用应该被翻译成LIKE –

+1

@SergeyBerezovskiy如果你在一个'string'上调用'Contains',那么是的,你问这个字符串是否包含一个子字符串。如果你在一组值上调用'Contains' *,你问的是该值是否在该集合中,而不是该值中的值的子字符串。 – Servy

+2

@SergeyBerezovskiy而这就是为什么他说它适用于OR语句的第一部分,但不是第二部分。第二部分是序列:'c.Place1.Select(e => e.PostCode).Contains(searchString)' –

1

您要搜索的每个PostCode的字符串值的部分值,但是您的代码将在邮政编码列表中搜索完整的搜索值。区别在于你把你的右括号放在哪里。

c.Practice1.Select(e => e.PostCode).Contains(searchString) 

VS

c.Practice1.Select(e => e.PostCode.Contains(searchString)) 

利用后者经过各PostCode的字符串和匹配字符串包含searchString,前者选择所有PostCode当时的中后期代码的列表中查找匹配到确切的searchString