2

我正在尝试针对 EF 实体类型(人)创建一般搜索查询。通常,搜索采用一个字符串,将其用逗号分隔,然后搜索其各种属性包含所有关键字的人。

我有一个名为 getProperties(Person p) 的函数,它接受一个实体(被实体类型覆盖),并返回一个由分隔符连接在一起的各种相关属性的字符串......例如:

John~Doe~Team A~Full Time

如果用户搜索“Team A, Full”,则应返回与上述展平实体相对应的人员……但是,如果输入“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();

好吧,它的工作原理是它与我期望的查询匹配,但由于它是静态的,它返回每个人的记录(很像 where(true) =P)

编辑第二个

更奇怪的是,如果我将结果存储到一个 var 中,然后在返回时返回带有断点的 var,执行永远不会到达断点......这个 linq 就像一个黑洞......我可以进入它,但是它永远不会让我回到我的 SearchPeople 方法......它只是处理上下文并忘记它。

编辑第三

如果我不立即调用 ToString() 并查看调试器中的 linq 表达式,它会显示“Linq to Entities 无法识别方法 getProperties(Person)”在没有 linq 窒息的情况下使用我的方法?

4

2 回答 2

0

你要返回一个列表?尝试返回类型为 List 或更改.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();
}
于 2012-11-30T17:20:46.380 回答
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;

烦人,但你去。

于 2012-11-30T18:29:15.070 回答