19 Stimmen

Generisches LINQ-Abfrageprädikat?

Nicht sicher, ob dies möglich ist oder ob ich richtig ausdrücke, wonach ich suche, aber ich habe folgendes Stück Code in meiner Bibliothek wiederholt und möchte etwas DRY üben. Ich habe eine Reihe von SQL Server-Tabellen, die ich basierend auf einem einfachen benutzerfreundlichen Suchfeld ala Google abfrage. Ich verwende LINQ, um die endgültige Abfrage basierend auf dem zu komponieren, was im Suchstring enthalten ist. Ich bin auf der Suche nach einer Möglichkeit, Generics und übergebene Lambda-Funktionen zu verwenden, um eine wiederverwendbare Routine daraus zu erstellen:

string[] arrayOfQueryTerms = getsTheArray();

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

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

Ich hatte gehofft, eine generische Methode mit einer Signatur zu erstellen, die so aussieht:

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

Ich verwende dieselbe Suchstrategie für alle meine Tabellen, daher unterscheidet sich das einzige, was wirklich von der Verwendung zur Verwendung variiert, von der durchsuchten MyTable & MyTableEntity und dem durchsuchten Feldnamen. Macht das Sinn? Gibt es eine Möglichkeit, mit LINQ dynamisch den Namen des Feldes zu übergeben, das in der WHERE-Klausel abgefragt werden soll? Oder kann ich dies als Prädikat-Lambda übergeben?

e => e.FieldName.Contains(queryTerm)

Ich weiß, dass es eine Million Möglichkeiten gibt, dies in SQL zu tun, wahrscheinlich einfacher, aber ich würde es lieben, alles in der LINQ-Familie für diese eine Angelegenheit zu behalten. Außerdem denke ich, dass Generics für ein Problem wie dieses nützlich sein sollten. Irgendwelche Ideen?

15voto

Erik Forbes Punkte 34383

Es hört sich so an, als ob Sie nach Dynamic Linq suchen. Sehen Sie sich das hier an. Dies ermöglicht es Ihnen, Zeichenfolgen als Argumente an die Abfrage-Methoden zu übergeben, wie:

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

Bearbeitung: Eine weitere Reihe von Beiträgen zu diesem Thema, die die dynamische Unterstützung von C# 4 verwenden: Teil 1 und Teil 2.

7voto

Quintin Robinson Punkte 78652

Was du hören möchtest, ist im Grunde genommen ein bedingter Prädikat-Generator..

Ich hoffe, du kannst das in etwas umformen, das du suchst. Viel Glück!

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

6voto

Mark Cidade Punkte 95914

Sie sollten sich vielleicht Ausdrucksbäume ansehen:

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

MemberInfo getmemberInfo(Expression expr)
 { var memberExpr = expr as MemberExpression;
   if (memberExpr != null) return memberExpr.Member;
   throw new ArgumentException();
 }

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

0voto

user17060 Punkte 402

Ich musste neulich dasselbe tun. Du wirst Dynamic Linq benötigen hier ist eine Möglichkeit, dies stark typisiert zu halten.

0voto

AliReza Sabouri Punkte 3235

Ich schlage vor, die Gridify Bibliothek auszuprobieren. Es ist viel einfacher zu arbeiten und hat auch bessere Leistung.

Verwendungsbeispiel:

query = dataSource.ApplyFiltering("FiledName=John");

Dies ist ein Leistungsvergleich zwischen dynamischen LINQ-Bibliotheken. enter image description here

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X