我有一个文本框,允许用户指定搜索字符串,包括通配符,例如:
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 };
但是我得到以下例外:
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获得相同的功能?
答案 0 :(得分:34)
var people = entities.People.Where("it.Name LIKE @searchTerm", new ObjectParameter("searchTerm", searchTerm));
答案 1 :(得分:12)
如何让它无缝地工作:
在您的EDMX模型中,添加:
<Function Name="String_Like" ReturnType="Edm.Boolean">
<Parameter Name="searchingIn" Type="Edm.String" />
<Parameter Name="lookingFor" Type="Edm.String" />
<DefiningExpression>
searchingIn LIKE lookingFor
</DefiningExpression>
</Function>
在开始的部分之后:
<edmx:ConceptualModels>
<Schema Namespace="Your.Namespace"...
然后,在代码中的任何位置添加此扩展方法:
//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, i.e. 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();
答案 2 :(得分:8)
嗯,您的选择是:
Contains
。我知道你不喜欢它,但它可能会起作用。答案 3 :(得分:3)
你可以这样做:
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<T>()
。在我的情况下,我发现我可以这样使用它,但它有任何副作用我不知道,也许它会在Entity
丢失一些功能。
答案 4 :(得分:2)
解决方案是使用SQLFunctions.PatIndex
var result = from c in items
where SqlFunctions.PatIndex(searchstring.ToLower(), c.fieldtoSearch) > 0
select c;
其中'searchstring'是要搜索的模式 'fieldtoSearch'是要搜索的字段
Patindex()支持使用字符串模式搜索进行搜索。搜索不区分大小写。
答案 5 :(得分:1)
您可以像这样使用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));
答案 6 :(得分:1)
现在,EF支持“ LIKE”用法,您可以使用所有sql通配符。检查一下。
var people = from t in entities.People
select new { t.Name };
people = people.Where(x => DbFunctions.Like(x.Name, searchTerm));
答案 7 :(得分:0)
var people = from t in entities.People
where t.Name.ToLower().Contains(searchTerm.ToLower())
select new { t.Name };
编辑 - 我可能会混合语法。我通常使用扩展方法;但是包含会起作用。
答案 8 :(得分:0)
过滤时不需要使用百分号。 e.g;
如果我想检查ItemName不包含&#39; - &#39;我会这样做
!Item.ItemName.Contains(&#34; - &#34)
在SQL中,它将转换为NOT LIKE&#39;% - %&#39;
答案 9 :(得分:0)
我们使用Database First和EntityFramework。
&#34;映射您自己的功能。&#34;方法与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查询中使用此方法。
答案 10 :(得分:0)
可以通过以下方法轻松实现
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")