如何使Linq扩展方法可用于实体? [英] How can I make Linq extension method available for the entities?
问题描述
我写了一个扩展System.Linq
类的方法.我的ContainsAnyWord
方法允许我针对字符串搜索字符串中的所有单词,而不是将一个字符串与另一个字符串进行比较.
I wrote a method that extends System.Linq
class. My ContainsAnyWord
method allows me to search all words in a string against a string instead of comparing one string to another.
这是我编写的扩展Linq
public static class LinqExtension
{
public static bool ContainsAnyWord(this string value, string searchFor)
{
if (!string.IsNullOrWhiteSpace(value) && !string.IsNullOrWhiteSpace(searchFor))
{
value = value.ToLower();
IEnumerable<string> tags = StopwordTool.GetPossibleTags(searchFor);
return tags.Contains(value);
}
return false;
}
}
此扩展方法在IEnumerable
对象上效果很好.但是当我想在IQueryable
对象上使用它时,出现以下错误
This extension method works great on an IEnumerable
object. But when I want to use it on IQueryable
object I get the following error
LINQ to Entities无法识别方法'Boolean ContainsAnyWord(System.String,System.String)'方法,以及此方法 无法转换为商店表达式.
LINQ to Entities does not recognize the method 'Boolean ContainsAnyWord(System.String, System.String)' method, and this method cannot be translated into a store expression.
以下示例非常有用,因为我正在使用列表.
The following example works great because I am working with a list.
using(var conn = new AppContext())
{
var allUsers = conn.Users.GetAll().ToList();
var foundUsers = allUsers.Where
(
user =>
user.FirstName.ContainsAnyWord("Some Full Name Goes Here")
|| user.LastName.ContainsAnyWord("Some Full Name Goes Here")
).ToList();
}
但是下面的示例不起作用,因为我正在使用IQueryable
,这给了我上面列出的错误.
But the following example does not work because I am working with IQueryable
which gives me the error listed above.
using(var conn = new AppContext())
{
var allUsers = conn.Users.Where
(
user =>
user.FirstName.ContainsAnyWord("Some Full Name Goes Here")
|| user.LastName.ContainsAnyWord("Some Full Name Goes Here")
).ToList();
}
如何解决此问题并使该方法可用于IQueryable
对象?
How can I fix this issue and make this method available for IQueryable
object?
已更新
根据我在下面得到的反馈,我尝试使用IQueryable
这样实现
Based on the feedback I got below, I tried to implement this using IQueryable
like so
public static IQueryable<T> ContainsAnyWord<T>(this IQueryable<T> query, string searchFor)
{
if (!string.IsNullOrWhiteSpace(searchFor))
{
IEnumerable<string> tags = StopwordTool.GetPossibleTags(searchFor);
return query.Where(item => tags.Contains(item));
}
return query;
}
但这也给我一个错误
推荐答案
您必须记住,必须在最后将其转换为SQL.
显然ContainsAnyWord无法转换为SQL ...
因此,将您的姓名保存在列表/数组中,然后尝试
You have to keep in mind that this has to be translated to SQL at the end.
Obviously ContainsAnyWord cannot be translated to SQL...
So ,save your names in a List/Array and try
user => yourlist.Contains( user.FirstName)
EF会将其转换为WHERE ..IN
EF will translate this to a WHERE ..IN
不需要方法,但是如果出于某些原因您想要它
There is no need for a method but if for some reason you want it
internal static class MyClass2
{
public static IQueryable<T> ContainsAnyWord<T>(this IQueryable<T> value, string searchFor) where T: User
{
var names = searchFor.Split(' ').ToList();
return value.Where(u => names.Contains(u.DisplayName));
}
}
您可以像使用它
var result=conn.Users.ContainsAnyWord("abc def ght");
这篇关于如何使Linq扩展方法可用于实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!