Ich versuche, mit LinqPad eine grundlegende dynamische Linq-Abfrage zu erstellen. Meine Methode fordert Benutzer auf, 1 bis 3 Optionen auszuwählen, und erstellt dann die Abfrage dynamisch basierend auf ihren Eingaben.
public void FilteredPropertySearch()
{
bool addAnotherOption = true;
int option;
Dictionary<int, bool> parameters = new Dictionary<int, bool>();
var predicate = PredicateBuilder.False<ResidentialProperty>();
Console.WriteLine("Follow instructions to filter property search results");
do
{
// get user input
option = int.Parse(Console.ReadLine());
switch(option)
{
case 1:
parameters.Add(1, true);
break;
// more cases - when case 0 addAnotherOption = false, loop ends
default:
Console.WriteLine("That was not a valid option");
break;
}
}while(addAnotherOption == true);
foreach(KeyValuePair<int, bool> p in parameters)
{
if(p.Key == 1 && p.Value == true)
predicate = predicate.Or (c => c.HasBackGarden);
if(p.Key == 2 && p.Value == true)
predicate = predicate.Or (c => c.HasFrontGarden);
if(p.Key == 3 && p.Value == true)
predicate = predicate.Or (c => c.HasSecureParking);
}
ResidentialProperties.Where (predicate).Dump();
}
Die foreach
Schleife sollte die Abfrage basierend auf den Benutzereingaben erstellen. Wenn ich jedoch beispielsweise den ersten Wert im Wörterbuch auf true setze und keine anderen auswähle, werden keine Ergebnisse zurückgegeben. Es sollte auf jeden Fall, wie ich weiß, einige Werte in meiner Datenbanktabelle enthalten, die erfüllen, dass Key(1)
wahr ist.
Sollte ich nach dem if
im foreach
etwas anderes mit query
tun?
BEARBEITEN
Ich habe stattdessen den Prädikaten-Generator verwendet und es scheint (irgendwie) zu funktionieren, wenn ich predicate.Or
verwende. predicate.Or
(gemäß bearbeitetem Code), aber es gibt nur die erste Option zurück, die ich auswähle, es wird kein Ausdrucksbaum erstellt. Ich dachte, dass das Ändern des predicate.Or
des predicate.And
jede ausgewählte Benutzereingabe zu einem Filterausdruck hinzugefügt hätte.
Wenn alle drei Optionen vom Benutzer ausgewählt wurden, möchte ich, dass nur Zeilen zurückgegeben werden, in denen die Spalten HasBackGarden, HasFrontGarden und HasSecureParking wahr sind. Wie schaffe ich das?
Wenn Sie Ihre Ergebnismenge auf die Datensätze beschränken möchten, die alle Bedingungen erfüllen, sollten Sie zu .And
anstelle von .Or
verwenden. .And
müssen Sie jedoch mit PredicateBuilder.True<ResidentialProperty>()
statt False
.
Dies liegt daran, dass die richtige Ergebnismenge vor dem Hinzufügen von Filtern alle Datensätze enthält und jeder nachfolgende Filter die Ergebnismenge einschränkt. Wenn Sie mit False
, kann keiner der Datensätze jemals das Prädikat erfüllen.
Aus Ihrem Code geht hervor, dass Sie mit der var "Abfrage" arbeiten, die eine leere Aufzählung ist. Denken Sie daran, was Sie als Abfrage bezeichnet haben, ist der Datensatz. Die Where-Anweisung ist die Abfrage für diesen Datensatz. Die erste Abfrage befindet sich also in einem leeren Datensatz, und es sieht so aus, als würden die zusätzlichen Abfragen von foreach diesen leeren Satz nur verfeinern.
Sie können auch einfach .Where (q => q.HasWhatever) ausführen, da dies Bools sind.