문제

LINQ를 사용하여 와일드 카드 검색을 수행 할 수 있는지 알고 싶습니다.

LINQ가 포함되어 있고, 시작, EndSwith 등을 포함합니다.

%테스트가%작동하는 경우%테스트와 같은 것을 원한다면 어떻게해야합니까?

문안 인사

도움이 되었습니까?

해결책

LINQ에서 SQL을 항상 사용하지는 않을 수 있으므로 일반 표현식을 사용합니다.

LINQ에서 객체의 예제와 마찬가지로

List<string> list = new List<string>();
list.Add("This is a sentence.");
list.Add("This is another one.");
list.Add("C# is fun.");
list.Add("Linq is also fun.");

System.Text.RegularExpressions.Regex regEx = new System.Text.RegularExpressions.Regex("This");

var qry = list
    .Where<string>(item => regEx.IsMatch(item))
    .ToList<string>();

// Print results
foreach (var item in qry)
{
    Console.WriteLine(item);
}

다른 팁

당신이 사용할 수있는 sqlmethods.like ().

사용의 예 :

var results =
        from u in users
        where SqlMethods.Like(u.FirstName, "%John%")
        select u;

사용 또는 가져 오기 목록에 System.Data.linq.sqlclient를 추가 한 다음 시도하십시오.

var results= from x in data
             where SqlMethods.Like(x.SearchField, “%something%like%this%”)
             select x;

을 위한 Entity Framework Core 2.0 거기 있습니다 LIKE 운영자 (2017 년 8 월에 발표):

var query = from e in _context.Employees
                    where EF.Functions.Like(e.Title, "%developer%")
                    select e;

질문을보고 있습니다

%테스트가%작동하는 경우%테스트와 같은 것을 원한다면 어떻게해야합니까?

그런 다음 나는 무언가를 기대하고 있습니다

LIKE '%Test if%it work%'

의미에 '테스트 if'와 'it 작동'이 포함되어야 함을 의미합니다. 그와 같은 순서로.

이것은 작동하지 않습니다.

context.SomeTable.Where(s => s.Name.Contains("Test if%it work")).ToList();

그리고 내가 사용하는 경우 :

context.SomeTable.Where(s => s.Name.Contains("Test if") && s.Name.Contains("it work")).ToList();

그런 다음 "테스트 if"와 "It Work"가 모두 포함 된 모든 레코드를 찾을 수 있습니다. 그러나 구체적으로 그 순서대로는 아닙니다.

그래서 포함 이건 불가능 해. 하지만 함께 인덱스 그것은이다.

indexof는 SearchString을 찾아 문자열에서 위치를 반환합니다. 올바른 순서로 단어를 찾을 수 있습니다.

-- 업데이트 --

나의 원래 대답을 통해 그것은 일반적인 솔루션을 제공하는 것이 나의 목표가 아니라 오히려 SQL 의존적이지 않은 다른 접근법의 예입니다. 따라서 원래의 예는 문자 그대로의 질문에만 답변하는 것이 맞습니다. 그러나 대답이 일반적인 경우 대답이 더 유용 할 수 있으므로, 나는 Where 명령문만큼 쉬운 쿼리에 같은 문을 추가 할 수있는 iquerable 확장을 작성했습니다. 확장은 LINQ에 대해 LINQ-SQL로 작동합니다.

이것은 그 순서대로 "테스트 if"와 "iT 작동"이 모두있는 모든 레코드를 찾을 것입니다.

context.SomeTable.Like("test if%it work", "Name").ToList();

listOfString.Like("test if%it work").ToList();

확장, 수많은 와일드 카드를 허용합니다.

/// <summary>
/// Allow to search the string with wildcards.
/// </summary>
/// <typeparam name="T">String or an object with a string member.</typeparam>
/// <param name="q">Original query</param>
/// <param name="searchstring">The searchstring</param>
/// <param name="memberName">The name of the field or null if not a field.</param>
/// <returns>Query filtered by 'LIKE'.</returns>
public static IQueryable<T> Like<T>(this IQueryable<T> q, string searchstring, string memberName = null)
{
    // %a%b%c% --> IndexOf(a) > -1 && IndexOf(b) > IndexOf(a) && IndexOf(c) > IndexOf(b)

    var eParam = Expression.Parameter(typeof(T), "e");

    MethodInfo methodInfo;

    // Linq (C#) is case sensitive, but sql isn't. Use StringComparison ignorecase for Linq.
    // Sql however doesn't know StringComparison, so try to determine the provider.
    var isLinq = (q.Provider.GetType().IsGenericType && q.Provider.GetType().GetGenericTypeDefinition() == typeof(EnumerableQuery<>));
    if (isLinq)
        methodInfo = typeof(string).GetMethod("IndexOf", new[] { typeof(string), typeof(StringComparison) });
    else
        methodInfo = typeof(string).GetMethod("IndexOf", new[] { typeof(string) });

    Expression expr;
    if (string.IsNullOrEmpty(memberName))
        expr = eParam;
    else
        expr = Expression.Property(eParam, memberName);

    // Split the searchstring by the wildcard symbol:
    var likeParts = searchstring.Split(new char[] { '%' }, StringSplitOptions.RemoveEmptyEntries);

    for (int i = 0; i < likeParts.Length; i++)
    {
        MethodCallExpression e;
        if (isLinq)
            e = Expression.Call(expr, methodInfo, new Expression[] { Expression.Constant(likeParts[i], typeof(string)), Expression.Constant(StringComparison.OrdinalIgnoreCase) });
        else
            e = Expression.Call(expr, methodInfo, Expression.Constant(likeParts[i], typeof(string)));

        if (i == 0)
        {
            // e.IndexOf("likePart") > -1
            q = q.Where(Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(e, Expression.Constant(-1, typeof(int))), eParam));
        }
        else
        {
            // e.IndexOf("likePart_previous")
            MethodCallExpression ePrevious;
            if (isLinq)
                ePrevious = Expression.Call(expr, methodInfo, new Expression[] { Expression.Constant(likeParts[i - 1], typeof(string)), Expression.Constant(StringComparison.OrdinalIgnoreCase) });
            else
                ePrevious = Expression.Call(expr, methodInfo, Expression.Constant(likeParts[i - 1], typeof(string)));

            // e.IndexOf("likePart_previous") < e.IndexOf("likePart")
            q = q.Where(Expression.Lambda<Func<T, bool>>(Expression.LessThan(ePrevious, e), eParam));
        }
    }
    return q;
}

SQLMethods가 필요하지 않기 때문에 MySQL 또는 PostgreSQL과 같은 모든 데이터베이스에 사용할 수 있다고 가정합니다. 그러나 나는 확실하지 않습니다. Entity Framework 6을 사용하여 SQL Server로 이것을 테스트했습니다. 위의 명령문은 SQL Server에서 다음 코드를 생성합니다.

SELECT [Extent1].* FROM SomeTable AS [Extent1]
WHERE ((( CAST(CHARINDEX(N'test if', [Extent1].[Name]) AS int)) - 1) > -1)
AND ((( CAST(CHARINDEX(N'test if', [Extent1].[Name]) AS int)) - 1) < 
     (( CAST(CHARINDEX(N'it work', [Extent1].[Name]) AS int)) - 1))

성능에 대해, '더 나은'이 무엇인지에 대한 논의가있는 것 같습니다 : Like 또는 Charindex. 그리고 내가 읽은 내용에서 Charindex가 가장 좋아하는 것 같습니다.

.Where( column LIKE "Pattern")
var result = (from x in db.Members
              where x.IDNumber.Contains(idnumber)
              && x.InstitutionIdentifier == institution.Identifier
              select x).ToList();
return result;

메모리에서 LINQ에서 SQL과 LINQ 모두에서 작동합니다.

나는 이것이 오래된 주제라는 것을 알고 있지만 여기에 매우 간단한 해결책이 있습니다.

string s=Regex.Escape("pattern - escaped for sanity").Replace("%", ".*").Replace("_", ".?");
user => Regex.IsMatch(user.FullName, s, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);

이 코드에서는 SQL 언어에 일반적인 탈출 문자를 사용하고 있습니다. 당신이 사용하고 싶다면 말하십시오 * 그리고 ?, 탈출 된 문자열에는 포함됩니다 \* 그리고 \? 이에 따라 포함하십시오 백 슬래시 .의 캐릭터 .Replace(...) 진술. 물론 사용자에게 RexEx 검색 기능을 제공하려면 패턴 문자열을 피하지 마십시오.

다른 옵션에 대한 Regex 자습서를 검색하십시오.

나는 정상적으로 믿는다 % 일치합니다 적어도 하나의 캐릭터, regex .* 일치합니다 0 이상 캐릭터. 실제로 % 와일드 카드는 더 비슷합니다 .+ (Greedy)보다는 (Greedy) .* (게으른).

도움이 되었기를 바랍니다.

linqtosql 또는 linq에 대해 이야기하는지 확실하지 않지만 다음과 같은 정기적 인 표현을 할 수 있습니다.

.Where(dto => System.Text.RegularExpressions.Regex.IsMatch(dto.CustomerName, @"Ad"));

Linq to Objects를 포함한 .NET 코드에서는 구현을 사용하고 있습니다. issqllikematch 스레드에서 기능 Regex를 사용하여 SQL의 "Like"Like 함수를 만듭니다..

사용의 예

bool ret = message.IsSqlLikeMatch(pattern);

내 게시물의 자세한 내용.NET에서 비교할 SQL의 "좋아요"패턴

당신은 또한 "contomate"를 사용할 수 있습니다.

var myresult = db.MyItems.Where(x=>x.MyField.Contains(mysearchstring));

LINQ를 물체 또는 LINQ에서 SQL에 대해 이야기하고 있습니까?

LINQ에서 개체에 의지해야합니다 정규 표현 나는 생각한다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top