简体   繁体   English

String.Replace in LINQ to Entities

[英]String.Replace in LINQ to Entities

I have an Asp.Net MVC 5 website and I want to search entities using LINQ. 我有一个Asp.Net MVC 5网站,我想使用LINQ搜索实体。 Currently I have a working search function. 目前我有一个工作搜索功能。 However, I want to add a feature which replaces characters in strings before running the search. 但是,我想在运行搜索之前添加一个替换字符串中字符的功能。 This is due to the fact that in Farsi, there are two similar representations of a single character and I want to run the search for both of them. 这是因为在波斯语中,单个字符有两个相似的表示,我想对它们进行搜索。

The working code is this (a very simplified version): 工作代码是这个(非常简化的版本):

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

what I want to do is this: 我想要做的是:

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

Obviously, this gives me the error: 显然,这给了我错误:

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

Currently the only thing that comes to my mind is to store the replaced strings into database and query those strings. 目前我唯一想到的就是将替换后的字符串存储到数据库中并查询这些字符串。 This is not a clean approach in my opinion. 在我看来,这不是一个干净的方法。 Another option is to run the query in code (query Restaurant s one by one) which isn't efficient at all. 另一个选择是在代码中运行查询(逐个查询Restaurant ),这根本没有效率。 Caching those values is going to help but again, I think there's a better way. 缓存这些值会有所帮助,但我认为还有更好的方法。 That's why I asked this question to see if there is some way to transfer this query to database. 这就是为什么我问这个问题,看看有没有办法将这个查询转移到数据库。

In Entity Framework 6 you can use command interceptors. 在Entity Framework 6中,您可以使用命令拦截器。 It sounds complicated, but they've made it easy as pie. 这听起来很复杂,但它们让它变得如此简单。

First create a class that implements System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor . 首先创建一个实现System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor的类。 Only one implemented method matters, the others can just be stubs: 只有一个实现的方法很重要,其他方法只能是存根:

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
}

And you activate the interceptor by calling 并通过调用激活拦截器

DbInterception.Add(new MyCommandInterceptor());

somewhere in the initialization of you application. 在应用程序初始化的某个地方。

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

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