如何使Linq扩展方法可用于实体? [英] How can I make Linq extension method available for the entities?

查看:70
本文介绍了如何使Linq扩展方法可用于实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个扩展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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆