복붙노트

[SQL] 어떻게 엔티티에 LINQ와 SQL 'LIKE'를 사용 하는가?

SQL

어떻게 엔티티에 LINQ와 SQL 'LIKE'를 사용 하는가?

나는 예를 들어, 와일드 카드를 포함하여, 사용자가 검색 문자열을 지정할 수있는 텍스트 상자를 가지고 :

Joh*
*Johnson
*mit*
*ack*on

엔티티에 LINQ를 사용하기 전에, 나는 매개 변수로 해당 문자열을 가져다가 한 저장 프로 시저를했다 :

SELECT * FROM Table WHERE Name LIKE @searchTerm

그리고 난 그냥 그것을 전달하기 전에 ( '%', '*')를하려면 string.replace 할 것입니다.

이제 LINQ와 엔티티에 나는 같은 일을 달성하기 위해 노력하고 있습니다. 내가 거기 StartsWith, EndsWith이고 지원이 포함되어 알고 있지만, 내가 필요로하는 방식을 지원하지 않습니다.

나는 "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를 사용하여이 동일한 기능을 얻을 것인가?

해결법

  1. ==============================

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

    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));
    
  2. ==============================

    2.어떻게 원활하게 작동하도록합니다 :

    어떻게 원활하게 작동하도록합니다 :

    귀하의 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>
    

    단지 시작 섹션 후 :

          <스키마 네임 스페이스 = "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();
    
  3. ==============================

    3.글쎄, 당신의 선택은 다음과 같습니다 :

    글쎄, 당신의 선택은 다음과 같습니다 :

  4. ==============================

    4.이 작업을 수행 할 수 있습니다 :

    이 작업을 수행 할 수 있습니다 :

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

    엔티티에 Linq는이 SQL에 () 메소드가 포함 변환,하지만 할 수 없기 때문에 SQL에 Linq에이 작업을 수행 할 수 있습니다. 나는 마침내 캐스팅을 수행 할 수있는 방법을 찾기 위해 노력, AsQueryable (), 또한 일반 버전 AsQueryable (). 나는 그것을 내 경우에는이 방법을 사용하여이 작업을 수행 할 수 있습니다 찾았지만, 그것이 내가 모르는이있는 부작용은, 어쩌면 법인에서 일부 기능을 잃게됩니다.

  5. ==============================

    5.이 같은 LINQ 이러한 모든 진술을 할 수있는

    이 같은 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. ==============================

    6.이 솔루션은 SQLFunctions.PatIndex을 사용하는 것입니다

    이 솔루션은 SQLFunctions.PatIndex을 사용하는 것입니다

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

    어디에서 검색 할 패턴입니다 '검색 문장'       'fieldtoSearch는'검색 할 수있는 분야입니다

    PATINDEX () 지원은 문자열 패턴 검색을 사용하여 검색. 검색 사례를 구분하지 않습니다.

  7. ==============================

    7.

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

    편집 - 나는 구문을 혼합 할 수 있습니다. 나는 보통 확장 방법을 사용; 하지만 의지 작업이 포함되어 있습니다.

  8. ==============================

    8.이제, EF 지원 "LIKE"사용하면 모든 SQL 와일드 카드를 사용할 수 있습니다. 이것 좀 봐.

    이제, EF 지원 "LIKE"사용하면 모든 SQL 와일드 카드를 사용할 수 있습니다. 이것 좀 봐.

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

    9.필터링 동안 사용 퍼센트 기호에 필요하지 않습니다. 예컨대;

    필터링 동안 사용 퍼센트 기호에 필요하지 않습니다. 예컨대;

    내가 포함되지 않은 항목 이름을 확인하려면 '-'나는 이런 식으로 할 것

    ! Item.ItemName.Contains ( "-")

    SQL에서 그것은 NOT LIKE로 변환됩니다 '% - %'

  10. ==============================

    10.우리는 데이터베이스, 제 1 및 EntityFramework를 사용합니다.

    우리는 데이터베이스, 제 1 및 EntityFramework를 사용합니다.

    "내 자신의 기능을지도." 방법은 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 단계 : 초기화 엔티티 Framework.CodeFirstStoreFunctions.

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

    5 단계 : 이제 당신이 당신의 LINQ 쿼리에서이 방법을 사용할 수 있습니다.

  11. ==============================

    11.그것은 쉽게 다음의 방법에 의해 달성된다

    그것은 쉽게 다음의 방법에 의해 달성된다

    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")
    
  12. from https://stackoverflow.com/questions/3095781/how-to-use-sql-like-with-linq-to-entities by cc-by-sa and MIT license