[英]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.