String.Replace in LINQ to Entities

时间:2014-02-20 08:29:45

标签: c# linq linq-to-sql linq-to-entities

我有一个Asp.Net MVC 5网站,我想使用LINQ搜索实体。目前我有一个工作搜索功能。但是,我想在运行搜索之前添加一个替换字符串中字符的功能。这是因为在波斯语中,单个字符有两个相似的表示形式,我想对它们进行搜索。

工作代码就是这个(非常简化的版本):

var model = db.Restaurants.Where(r => r.Name.ToUpper().Contains(query));

我想做的是:

query = query.Replace('آ', 'ا'); //couple of other fixes too...
var model = db.Restaurants.Where(r => r.Name.ToUpper().Replace('آ', 'ا').Contains(query));

显然,这给了我错误:

LINQ to Entities does not recognize the method 'System.String Replace(Char, Char)' method, and this method cannot be translated into a store expression

目前我唯一想到的就是将替换后的字符串存储到数据库中并查询这些字符串。在我看来,这不是一个干净的方法。另一种选择是在代码中运行查询(逐个查询Restaurant),这根本就没有效率。缓存这些值会有所帮助,但我认为还有更好的方法。这就是为什么我问这个问题,看看是否有办法将这个查询转移到数据库。

1 个答案:

答案 0 :(得分:4)

在Entity Framework 6中,您可以使用命令拦截器。这听起来很复杂,但它们让它变得简单。

首先创建一个实现System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor的类。只有一个实现的方法很重要,其他方法只能是存根:

public class MyCommandInterceptor : IDbCommandInterceptor
{
    public void ReaderExecuting(DbCommand command,
                DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        command.CommandText = command.CommandText.Replace("a", "b");
    }

    public void NonQueryExecuting(DbCommand command, 
                DbCommandInterceptionContext<int> interceptionContext)
    { }

    ... lots of stubs
}

通过调用

激活拦截器
DbInterception.Add(new MyCommandInterceptor());

在应用程序初始化的某个地方。

相关问题