2012-11-30 56 views
2

我正在尝试针对EF实体类型(人)创建一个通用搜索查询。通常,搜索需要一个字符串,用逗号分割,然后搜索各种属性包含所有关键字的人员。如何在linq where子句中使用函数的返回值?

我有一个函数调用的GetProperties(人员P),其采用实体(由实体类型覆盖),并返回相关的各种属性的字符串用分隔符连接在一起...如:

John~Doe~Team A~Full Time 

如果用户搜索与上述扁平化实体相对应的“团队A,完整”人员应该返回......但是,如果输入“John,Smith”,则不应该。

我认为有以下期待权,但它只是不工作...

public IEnumerable<Person> SearchPeople(string searchString) 
{ 
    if (searchString == null || string.IsNullOrEmpty(searchString.Trim())) 
     return base._objectSet.ToList(); 

    string[] SearchWords = searchString.Split(',').Select(s => s.Trim()).ToArray(); 

    return (from person 
      in  base._objectSet 
      let  t = (getProperties(person)) 
      where SearchWords.All(word => t.Contains(word)) 
      select person).ToList(); 
} 

和GetProperties中的功能是:

public static string getProperties(Person p) 
{ 
    string[] values = { p.Surname, p.GivenName, p.Team, p.Status }; 
    return values.Aggregate((x, y) => String.IsNullOrEmpty(y) ? x : string.Concat(x, "~", y)); 
} 

有谁看到我要去哪里错了?

编辑

没有异常升高,但是当我通过代码,当我到了LINQ,它便在承载查询的UnitOfWork的Dispose方法。很奇怪。

如果我改变它,这样它搜索对一个硬编码字符串,它按预期工作:

var test = (from person 
      in  base._objectSet 
      where SearchWords.All(word => "John~Doe~Team A~Full Time".Contains(word)) 
      select person).ToList(); 

好,它的工作原理,它期望它的查询相匹配,但因为它是静态的,它返回每个人的记录(很像有地方(真)= P)

编辑第二

更奇怪的是,如果我存储结果到一个变种,然后用返回的VAR Retu上的断点执行从未到达断点......这个linq就像一个黑洞......我可以进入它,但它永远不会让我回到我的SearchPeople方法......它只是放置上下文并忘记它。

编辑第三

如果我不叫的ToString()马上看看在调试器中的LINQ表达式,它说:“LINQ到实体无法识别方法GetProperties(人)”看上去就像它无声地窒息了我的方法...任何方式来使用我的方法没有LINQ窒息它?

+4

你能解释为什么'它不起作用?' –

回答

0

您正在返回一个列表?尝试返回类型是一个列表或改变.ToList()AsEnumerable()

public List<Person> SearchPeople(string searchString) 
{ 
    if (searchString == null || string.IsNullOrEmpty(searchString.Trim())) 
     return base._objectSet.ToList(); 

    string[] SearchWords = searchString.Split(',').Select(s => s.Trim()).ToArray(); 

    return (from person 
      in  base._objectSet 
      let  t = (getProperties(person)) 
      where SearchWords.All(word => t.Contains(word)) 
      select person).ToList(); 
} 
+0

列表获取隐式转换为IEnumerable。据我所知,没有任何区别。我测试了它,以防万一我错了,但使用List时没有改变。 – Chronicide

0

好了,发现自己的LINQ 2的entites不喜欢的方法(如不知道如何翻译成SQL)后,我重写了我的linq是一个非常繁琐但功能的方式:

var people = from p 
      in  base._objectSet 
      where SearchWords.All(p.GivenName.Contains(word) || p.Surname.Contains(word) || p.(???).Contains(word) || etc.) 
        select p; 

恼人的,但你去。

相关问题