| 

.NET C# Java Javascript Exception

6
Hallo zusammen,

es gibt eine Entität in der Datenbank mit mehreren Feldern.
Der Benutzer soll die Möglichkeit haben die Tabelle durchzusuchen.
Dabei kann er (wenn es um einen Kunden geht) z.B. Namen und/oder Plz. und/oder Branche angeben.

Ich könnte für jede Variation jetzt eine Expression schreiben:

if (example.a.HasValue && example.b.HasValue)
{
items = list.Where(x => x.a == example.a && x.b == example.b);
}
else if (example.b.HasValue)
{
items = list.Where(x => x.b == example.b);
}
else if (example.a.HasValue)
{
items = list.Where(x => x.a == example.a);
}


was bei vielen Kombinationsmöglichkeiten sehr lästig wäre.

Also hätte ich viel lieber sowas:

var expressions = new List<Expression<Func<blah, bool>>>();

if (example.a.HasValue)
{
expressions.Add(x => x.a == example.a);
}
if (example.b.HasValue)
{
expressions.Add(x => x.b == example.b);
}

foreach (var expression in expressions)
{
//irgendwie zu finalExpression kombinieren
}

items = list.Where(finalExpression);


Wie kriegt man sowas hin?(es kann nicht der erste mit dieser Frage sein, aber ich finde irgendwie keine Antwort darauf)

Danke im Voraus
lj
19.01.2012
lj_1900 45 1 4
3 Antworten
4
Ein sehr interessantes Thema. Das ganze nennt sich dann Dynamic Lambda, also Lambda-Ausdrucke die zur Laufzeit erzeugt werden.
Um solche dynamischen Lambda-Ausdrucke zu erzeugen solltest du auf jedenfall die Grundlagen von Reflection mal überflogen haben und dich mit der Funktionsweise von Lambda auskennen.

Dieser Codeproject erklärt die vorgehensweise sehr gut:
The Workings of Dynamic Lambda in LINQ

Du kannst aber auch den Weg über den PredicateBuilder gehen. Mit dem hab ich sowas selbst zwar noch nicht gemacht aber es klingt interessant und sollte einfacher sein als Dynamic Lambda. Der PredicateBuilder ist Bestandteil des LINQKit's. Hier gibt es dann Lambda-Methoden wie .Or und .And. Eine Einführung dazu findest du hier: Dynamically Composing Expression Predicates.

Viel Erfolg.
19.01.2012
Floyd 14,6k 3 9
Danke, genau das habe ich gesucht (LinqKit).
lj_1900 23.01.2012
1
Verknüpfen sollte mit

Expression.And()

funktionieren


Edit: was aber eine BinaryExpression zurückgibt..

Eine einfach Möglichkeit wäre
var items = ...;
foreach (var expression in expressions)
{
items = items.Where(expression);
}



Edit 2: Ich hab's nicht getestet, aber die vielleicht funktioniert es ja - ein Wrapper um Expression.AndAlso

http://stackoverflow.com/questions/2553805/linq-to-sql-combine-expressions
19.01.2012
WolfgangKluge 1,0k 2 7
bzw. AndAlso
WolfgangKluge 19.01.2012
Expression.And() (entspricht dem '&' Operator) und Expression.AndAlso() ('&&') liefern BinaryExpression zurück.

ObjectSet<blah>.Where(Expression<Func<blah, bool>> where) kommt damit nicht klar. Mach ich was falsch?
lj_1900 19.01.2012
Nein, hast natürlich Recht. Siehe edit (für && - Kombinationen)
WolfgangKluge 19.01.2012
0
Hallo,

wie wäre es mit:
var results = list
.Where(item => !example.a.HasValue || item.a == example.a)
.Where(item => !example.b.HasValue || item.b == example.b)
...;


[Edit]
Achso, du kannst natürlich auch die Bedingungen direkt verknüpfen:

IQueryable<TItem> result = items.AsQueryable();

if (example.a.HasValue)
results = results .Where(item => item.a == example.a)
if (example.b.HasValue)
results = result.Where(item => item.b == example.b)
...;
19.01.2012
Tachyon 690 1 7
Tachyon 690 1 7
Was aber so garnicht dynamisch ist. Wenn der Nutzer selber bestimmen soll welche Daten wie gefiltert werden sollen wird das ne ziehmliche Fummelarbeit.
Floyd 19.01.2012
Danke, aber leider kann ich mit der Vorgehensweise nichts anfangen, denn ich habe keinen direkten Zugriff auf die IQueryable<> Collection, sonder übergebe die Expression als Parameter ein ein Method.
lj_1900 23.01.2012

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH