C# 如何使用SQL';比如';使用LINQ到实体?

C# 如何使用SQL';比如';使用LINQ到实体?,c#,sql,linq-to-entities,C#,Sql,Linq To Entities,我有一个文本框,允许用户指定搜索字符串,包括通配符,例如: Joh* *Johnson *mit* *ack*on 在使用LINQ to Entities之前,我有一个存储过程,它将该字符串作为参数并执行以下操作: SELECT * FROM Table WHERE Name LIKE @searchTerm 然后我只做一个String.Replace('*','%'),然后再传入它 现在有了LinqTo实体,我正试图完成同样的事情。我知道有StartsWith、EndsWith和Conta

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

Joh*
*Johnson
*mit*
*ack*on
在使用LINQ to Entities之前,我有一个存储过程,它将该字符串作为参数并执行以下操作:

SELECT * FROM Table WHERE Name LIKE @searchTerm
然后我只做一个String.Replace('*','%'),然后再传入它

现在有了LinqTo实体,我正试图完成同样的事情。我知道有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.
我如何使用LINQtoEntities获得相同的功能

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

编辑-我可能在混合语法。我通常使用扩展方法;但是包含将起作用。

好吧,您的选择是:

  • 使用
    包含
    。我知道你不喜欢它,但它可能会被用来工作
  • 从中选择一个函数。它们都在L2E中得到支持
  • +1至@Yury表示ESQL

您可以这样做:

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

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

中失去一些功能如何让它无缝工作:

在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>
就在这里

现在您可以执行以下操作:

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


您可以像这样使用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));
解决办法是使用

其中“searchstring”是要搜索的模式 “fieldtoSearch”是要搜索的字段


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

过滤时不需要使用百分号。e、 g

如果我想检查ItemName不包含“-”,我会这样做

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));
!!Item.ItemName.Contains(“-”)


在SQL中,它将转换为与“%-%”不同的值。

我们首先使用数据库和EntityFramework

“映射您自己的功能”方法与nuget一起适用于我们

第一步:在数据库中创建一个函数,如下所示:

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类中创建了我的方法):

第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")


除此之外,contains将自动将整个搜索词包装在通配符中。如果用户想要所有名字以“Mar”开头的人怎么办Mary Marissa Omar Jamaraquoui返回(名字已被更改以保护无辜者),更奇怪的是,它还添加了一个“~”。对于空白搜索项,搜索项为“%”。当它查询数据库时,所包含的内容将其转换为:@p\u linq\u 2=N“%$%%”该~可能被用作转义字符,以表明它正在查找包含文本“%”的字符串。如果您要使用Contains(它处理wild carding),那么您也不能尝试处理wild carding。。。在提出SQL时,是否足够聪明地知道底层数据库是否区分大小写?这更适用于StartWith,但.ToLower可能会扼杀索引的使用。@Tom-你知道,我甚至不确定。这是一个很好的问题,今晚我可能需要做一些比赛……我不“讨厌”他。它没有按预期的那样工作,请参见下面我对Mike M的回复。SqlFunctions中没有包含LIKE子句的内容。map your own函数是显而易见的,本质上就是我一直在做的,但这似乎是一个简单的问题,它将得到本机支持。在
包含
开始时使用
结束时使用
之间,您可以选择所需的通配符。我相信这涵盖了您的所有情况。是的,我会使用Contains、StartsWith和EndsWith-这些SQLMETHODS同样适用于您flaky@CraigStuntzSqlFunctions链接是broken@BrianWebster链接已更新指定的方法“类似布尔值”(System.String,System.String)无法将类型“…SearcherHelper”上的“”转换为LINQ to Entities存储表达式。:(我不明白这是如何工作的,因为在我的例子中,应用程序没有运行扩展方法…关于功能的详细描述??EDMX行(如上)将使其与LINQ to Entities一起工作。对于非LINQ to Entities,方法将被调用LINQ方法不起作用,我不知道为什么。你能帮我吗?Edmx行可以,扩展可以,现在我不知道我还能做些什么才能从…何处…像
。在EF6中不再支持,因为函数必须是可组合的。但是不能定义可组合函数commandtext.var people=entities.people.Where(“it.Name,如“%”++@searchTerm++“%””,new ObjectParameter(“searchTerm”,searchTerm));@EvgeniNabokov,只有在
searchTerm
中尚未包含百分号时才需要该函数。获取错误信息“没有重载方法,其中包含2个参数”。你知道为什么吗?如果你不想使用泛型查询,你可以在这里查看我的答案:好的简单解决方案。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Add(new FunctionsConvention("dbo", this.GetType()));
}
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")