如何在LINQ to Entities中使用SQL’LIKE’?

我有一个文本框,允许用户指定搜索字符串,包括通配符,例如:

Joh* *Johnson *mit* *ack*on 

在使用LINQ to Entities之前,我有一个存储过程,它将该字符串作为参数并执行:

 SELECT * FROM Table WHERE Name LIKE @searchTerm 

然后我会在传入之前执行String.Replace(’*’,’%’)。

现在有了LINQ to Entities,我正在尝试完成同样的事情。 我知道有StartsWith,EndsWith和Contains支持,但它不会以我需要的方式支持它。

我读到了“SqlMethods.Like”并尝试了这个:

 var people = from t in entities.People where SqlMethods.Like(t.Name, searchTerm) select new { t.Name }; 

但是我得到以下exception:

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

如何使用LINQ to Entities获得相同的function?

http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/6529a35b-6629-44fb-8ea4-3a44d232d6b9/

 var people = entities.People.Where("it.Name LIKE @searchTerm", new ObjectParameter("searchTerm", searchTerm)); 

如何让它无缝地工作:

在您的EDMX模型中,添加:

      searchingIn LIKE lookingFor   

在开始的部分之后:

然后,在代码中的任何位置添加此扩展方法:

  //prior to EF 6 [System.Data.Objects.DataClasses.EdmFunction("Your.Namespace", "String_Like")] //With EF 6 [System.Data.Entity.DbFunction("Your.Namespace", "String_Like")] public static bool Like(this string input, string pattern) { /* Turn "off" all regular expression related syntax in * the pattern string. */ pattern = Regex.Escape(pattern); /* Replace the SQL LIKE wildcard metacharacters with the * equivalent regular expression metacharacters. */ pattern = pattern.Replace("%", ".*?").Replace("_", "."); /* The previous call to Regex.Escape actually turned off * too many metacharacters, ie those which are recognized by * both the regular expression engine and the SQL LIKE * statement ([...] and [^...]). Those metacharacters have * to be manually unescaped here. */ pattern = pattern.Replace(@"\[", "[").Replace(@"\]", "]").Replace(@"\^", "^"); return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase); } 

你有它。

现在你可以这样做:

 (from e in Entities where e.Name like '%dfghj%' select e) 

要么

 string [] test = {"Sydney", "Melbourne", "adelaide", "ryde"}; test.Where(t=> t.Like("%yd%e%")).Dump(); 

那么,你的选择是:

  • 使用Contains 。 我知道你不喜欢它,但它可能会起作用。
  • 从SqlFunctions中选择一个函数。 L2E都支持它们。
  • 映射您自己的function 。
  • ESQL为@Yury +1。

你可以这样做:

 using System.Data.Entity; // EntityFramework.dll v4.3 var queryResult=db.Accounts.AsQueryable().Where(x => x.Name.Contains(queryKey)); 

因为Linq to Entity无法将方法Contains()转换为SQL,但Linq to SQL可以做到这一点。 我试图找到一个可以进行AsQueryable()的方法,最后是AsQueryable() ,也是一个通用版本AsQueryable() 。 在我的情况下,我发现我可以这样使用它,但它有任何副作用,我不知道,也许它会失去Entity一些function。

解决方案是使用SQLFunctions.PatIndex

 var result = from c in items where SqlFunctions.PatIndex(searchstring.ToLower(), c.fieldtoSearch) > 0 select c; 

其中’searchstring’是搜索’fieldtoSearch’的模式,是要搜索的字段

Patindex()支持使用字符串模式搜索进行搜索。 搜索不区分大小写。

您可以像这样使用LINQ执行所有这些语句

 string _search = "johnson"; // joh* OR joh% items.Where(i => i.Name.StartsWith(_search, StringComparison.OrdinalIgnoreCase)); // *son OR %son items.Where(i => i.Name.EndsWith(_search, StringComparison.OrdinalIgnoreCase)); // *hns* OR %hns% items.Where(i => i.Name.ToLower().Contains(_search)); 
 var people = from t in entities.People where t.Name.ToLower().Contains(searchTerm.ToLower()) select new { t.Name }; 

编辑 – 我可能会混合语法。 我通常使用扩展方法; 但包含将工作。

过滤时不需要使用百分号。 例如;

如果我想检查ItemName不包含’ – ‘我将这样做

!Item.ItemName.Contains( “ – ”)

在SQL中,它将转换为NOT LIKE’% – %’

我们使用Database First和EntityFramework。

“映射你自己的function”。 方法与nuget EntityFramework.CodeFirstStoreFunctions一起为我们工作。

1步骤:在db中创建一个函数,如下所示:

 CREATE FUNCTION [dbo].[StringLike] ( @a nvarchar(4000), @b nvarchar(4000) ) RETURNS bit AS BEGIN RETURN (SELECT CASE WHEN (SELECT 1 WHERE @a LIKE @b) = 1 THEN 1 ELSE 0 END) END 

2步骤:安装nuget EntityFramework.CodeFirstStoreFunctions

3步骤:在代码中创建一个这样的方法(我在DbContext类中创建我的方法):

 [DbFunction("CodeFirstDatabaseSchema", "StringLike")] public static bool Like(string input, string pattern) { throw new NotSupportedException("Direct calls are not supported."); } 

4步骤:初始化EntityFramework.CodeFirstStoreFunctions。

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Add(new FunctionsConvention("dbo", this.GetType())); } 

5步骤:现在您可以在linq查询中使用此方法。

现在,EF支持“LIKE”用法,您可以使用所有sql通配符。 看一下这个。

 var people = from t in entities.People select new { t.Name }; people = people.Where(x => DbFunctions.Like(x.Name, searchTerm)); 

通过以下方法很容易实现

 var people = from t in entities.People where t.Name.Contains(searchTerm) select new { t.Name }; 

使用以下规范来实现通配符

 LIKE 'a%' => StartsWith("a") LIKE '%a' => EndsWith("a") LIKE '%a%' => Contains("a") LIKE 'a%b' => StartsWith("a") && EndsWith("b") LIKE '%a%b%' => StartsWith("a") && Contains("b")