繁体   English   中英

如何在linq where子句中使用函数的返回值?

[英]How to use the return value of a function in a linq where clause?

我正在尝试针对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扼杀吗?

您要返回列表? 尝试将返回类型设为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();
}

好吧,在发现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;

烦人,但是你去了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM