문제

목록이 있습니다<string> 변수 카운트의 경우 텍스트 열에 해당 문자열이 포함 된 항목을 찾기 위해 (LINQ를 통해) 테이블을 쿼리하려고합니다.

이것을 시도했습니다 (작동하지 않음) :

items = from dbt in database.Items
         where (stringList.FindAll(s => dbt.Text.Contains(s)).Count > 0)
         select dbt;

쿼리는 다음과 같습니다.

select * from items where text like '%string1%' or text like '%string2%'

이게 가능해?

도움이 되었습니까?

해결책

원하는 대로이 기사를 확인하십시오.
http://www.albahari.com/nutshell/predicatebuilder.aspx

이것은 꿈처럼 작동합니다. 나는 본질적으로 그들의 코드를 자르고 붙여 넣고 이것을 다시 가져 왔습니다 (물론 내 데이터 체계와 함께).

SELECT [t0].[Id], [t0].[DateCreated], [t0].[Name] ...
FROM [dbo].[Companies] AS [t0]
WHERE ([t0].[Name] LIKE @p0) OR ([t0].[Name] LIKE @p1)

개념 증명을 위해 실행 한 코드는 다음과 같습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace PredicateTest
{
class Program
{
    static void Main(string[] args)
    {
        DataClasses1DataContext dataContext = new DataClasses1DataContext();

        Program p = new Program();
        Program.SearchCompanies("test", "test2");
        var pr = from pi in  dataContext.Companies.Where(Program.SearchCompanies("test", "test2")) select pi;
    }

    DataClasses1DataContext dataContext = new DataClasses1DataContext();

    public static Expression<Func<Company, bool>> SearchCompanies(
                                                  params string[] keywords)
    {
        var predicate = PredicateBuilder.False<Company>();
        foreach (string keyword in keywords)
        {
            string temp = keyword;
            predicate = predicate.Or(p => p.Name.Contains(temp));
        }
        return predicate;
    }

}

public static class PredicateBuilder
{
    public static Expression<Func<T, bool>> True<T>() { return f => true; }
    public static Expression<Func<T, bool>> False<T>() { return f => false; }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                        Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
              (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                         Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
        return Expression.Lambda<Func<T, bool>>
              (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
    }
}
}

코드와 설명을 위해 사이트로 이동하는 것이 좋습니다.

(진술이 필요한 경우 잘 작동하기 때문에 첫 번째 답변을 남기고 있습니다)

다른 팁

전체 LINQ에서 SQL 게임을 처음 접지만이 구문이 도움이됩니까?

string[] items = new string[] { "a", "b", "c", "d" };

var items = from i in db.Items
             where items.Contains(p.text)
            select i;

가져 왔습니다 :

http://blog.wekeroad.com/2008/02/27/creating-in-queries-with-linq-teql/

이 게시물을 읽은 후, 당신과 동일한 솔루션을 찾은 후에는 솔루션을 찾았습니다. .Any 그리고 .All LINQ를위한 방법은 어레이에 대한 결과를 얻는 멋진 간단하고 우아한 방법입니다.

이 인스턴스에서는 쉼표로 구분 된 검색 입력을 사용하고 있습니다. 경기가 같은 경우에 상관 없습니다.

var qry = Query.Split(',').Select(c => c.Trim().ToLower());

먼저 LINQ에서 SQL로 또는 어디에서나 일부 데이터를 쿼리로 가져옵니다.

var search = db.tablename;

멋진 타이트 코드를 위해 Lambda 구문을 사용하여 일치합니다. .Any 테이블의 이름 또는 설명으로 쿼리의 문자열.

search = search.Where(
    record => 
    qry.Any(q => record.Name.ToLower().Contains(q)) || 
    qry.Any(q => record.Description.ToLower().Contains(q)));

모든 문자열이 모든 필드 내에서 일치하는 결과 만 원한다면 교체 할 수 있습니다. .Any ~와 함께 .All:

search = search.Where(
    record => 
    qry.All(q => record.Name.ToLower().Contains(q)) || 
    qry.All(q => record.Description.ToLower().Contains(q)));

사용 :

string searh = "test1 test2,test3";    
data.Persons.Search(p => p.Name, search);

검색 기능은 다음과 같습니다.

public static IQueryable<T> Search<T>(this IQueryable<T> source, Expression<Func<T, string>> selector, string s)
{
    if (string.IsNullOrEmpty(s))
        return source;

    string[] str = s.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);

    MethodInfo methodContains = typeof(string).GetMethod("Contains", new[] { typeof(string) });

    Expression strExpression;
    Expression expressionContains;
    Expression resultExpression = Expression.Empty();

    for (int i = 0; i < str.Length; i++)
    {
        strExpression = Expression.Constant(str[i].Trim(), typeof(string));
        expressionContains = Expression.Call(selector.Body, methodContains, strExpression);

        if (i == 0)
            resultExpression = expressionContains;
        else
            resultExpression = Expression.OrElse(resultExpression, expressionContains);
    }

    Expression<Func<T, bool>> lambdaExpr = Expression.Lambda<Func<T, bool>>(resultExpression, new ParameterExpression[] { selector.Parameters[0] });

    return source.Where(lambdaExpr);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top