Pergunta

Não sei se isso é possível ou se eu estou expressando corretamente o que eu estou procurando, mas eu tenho o seguinte trecho de código na minha biblioteca várias vezes e gostaria de praticar algum DRY. Eu tenho um conjunto de tabelas do SQL Server que eu estou consultando com base em um campo de pesquisa fornecido pelo usuário simples ala Google. Eu estou usando LINQ para compor a consulta final com base no que está na cadeia de pesquisa. Eu estou procurando uma maneira de genéricos de uso e passou em funções lambda para criar uma rotina reutilizável fora deste:

string[] arrayOfQueryTerms = getsTheArray();

var somequery = from q in dataContext.MyTable
                select q;

if (arrayOfQueryTerms.Length == 1)
{
    somequery = somequery.Where<MyTableEntity>(
        e => e.FieldName.StartsWith(arrayOfQueryTerms[0]));
}
else
{
    foreach(string queryTerm in arrayOfQueryTerms)
    {
        if (!String.IsNullOrEmpty(queryTerm))
        {
            somequery = somequery 
                        .Where<MyTableEntity>(
                            e => e.FieldName.Contains(queryTerm));
        }
    }
}

Eu estava esperando para criar um método genérico com a assinatura que é algo como:

private IQueryable<T> getQuery(
    T MyTableEntity, string[] arrayOfQueryTerms, Func<T, bool> predicate)

Eu estou usando a mesma estratégia de busca em todas as minhas tabelas, então a única coisa que realmente difere de uso para uso é o MyTable & MyTableEntity procurou eo FieldName procurou. Isso faz sentido? Existe uma maneira com LINQ para passar dinamicamente o nome do campo para consulta na cláusula onde? Ou eu posso passar isso como um lambda predicado?

e => e.FieldName.Contains(queryTerm)

Eu percebo formas há um milhão e meio de fazer isso em SQL, provavelmente mais fácil, mas eu gostaria de manter tudo na família LINQ para este. Além disso, eu sinto que os genéricos devem ser útil para um problema como este. Alguma idéia?

Foi útil?

Solução

Parece que você está procurando Dinâmico Linq. Dê uma olhada aqui . Isso permite que você passar cadeias como argumentos para os métodos de consulta, como:

var query = dataSource.Where("CategoryID == 2 && UnitPrice > 3")
                      .OrderBy("SupplierID");

Edit: Outro conjunto de posts sobre o assunto, usando C # suporte dinâmico 4 de: Parte 1 e Parte 2 .

Outras dicas

O que parece é que você quer, basicamente, uma condicional predicado construtor ..

Eu espero que você pode moldar isso em algo que você está procurando, boa sorte!

http://www.albahari.com/nutshell/predicatebuilder.aspx

Você pode querer olhar para as árvores de expressão:

IQueryable<T> getQuery<T>(T myTableEntity, string[] arrayOfQueryTerms, Expression<Func<T, bool>> predicate)
 { var fieldOrProperty = getMemberInfo(predicate);
   /* ... */
 }

MemberInfo getmemberInfo<T>(Expression<Func<T,bool> expr)
 { var memberExpr = expr as MemberExpression;
   if (memberExpr != null) return memberExpr.Member;
   throw new ArgumentException();
 }

var q = getQuery<FooTable>(foo, new[]{"Bar","Baz"}, x=>x.FieldName);

Recentemente, tive de fazer a mesma coisa. Você vai precisar Dinâmico Linq < a href = "http://talesfromthebleedingedge.blogspot.com/2008/10/linq-to-entities-dynamic-linq-to.html" rel = "nofollow noreferrer"> aqui é uma maneira de manter esta fortemente tipado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top