Ich habe ein Kendo UI-Raster, das derzeit das Filtern nach mehreren Spalten zulässt. Ich frage mich, ob es einen alternativen Ansatz gibt, um die äußere switch-Anweisung zu entfernen.
Grundsätzlich möchte ich in der Lage sein, eine Erweiterungsmethode zu erstellen, damit ich nach a filtern kann, IQueryable<T>
und ich möchte die äußere case-Anweisung löschen, damit ich die Spaltennamen nicht wechseln muss.
private static IQueryable<Contact> FilterContactList(FilterDescriptor filter, IQueryable<Contact> contactList)
{
switch (filter.Member)
{
case "Name":
switch (filter.Operator)
{
case FilterOperator.StartsWith:
contactList = contactList.Where(w => w.Firstname.StartsWith(filter.Value.ToString()) || w.Lastname.StartsWith(filter.Value.ToString()) || (w.Firstname + " " + w.Lastname).StartsWith(filter.Value.ToString()));
break;
case FilterOperator.Contains:
contactList = contactList.Where(w => w.Firstname.Contains(filter.Value.ToString()) || w.Lastname.Contains(filter.Value.ToString()) || (w.Firstname + " " + w.Lastname).Contains( filter.Value.ToString()));
break;
case FilterOperator.IsEqualTo:
contactList = contactList.Where(w => w.Firstname == filter.Value.ToString() || w.Lastname == filter.Value.ToString() || (w.Firstname + " " + w.Lastname) == filter.Value.ToString());
break;
}
break;
case "Company":
switch (filter.Operator)
{
case FilterOperator.StartsWith:
contactList = contactList.Where(w => w.Company.StartsWith(filter.Value.ToString()));
break;
case FilterOperator.Contains:
contactList = contactList.Where(w => w.Company.Contains(filter.Value.ToString()));
break;
case FilterOperator.IsEqualTo:
contactList = contactList.Where(w => w.Company == filter.Value.ToString());
break;
}
break;
}
return contactList;
}
Einige zusätzliche Informationen, ich verwende NHibernate Linq. Ein weiteres Problem ist, dass die Spalte "Name" in meinem Raster tatsächlich "Vorname" + "" + "Nachname" in meiner Kontaktentität ist. Wir können auch davon ausgehen, dass alle filterbaren Spalten Zeichenfolgen sind.
BEARBEITEN Denken Sie daran, dass dies mit NHibernate Linq und AST funktionieren muss .
quelle
Antworten:
Beantwortung Ihrer spezifischen Frage ,
Im Fall von "Name" nennen Sie es als;
Sie sollten eine Überladung hinzufügen als,
Sie können es also so für das Feld "Firma" nennen.
Dies verhindert, dass der Aufrufer gezwungen wird, ein Array zu erstellen, wenn er nur ein Feld / eine Eigenschaft auswählen möchte.
Was Sie wahrscheinlich suchen, ist wie folgt
Um diese Logik vollständig um die Definition des zu entfernen
selector
undpredicate
benötigen Sie weitere Informationen darüber, wie der Filter aufgebaut ist. Wenn möglich, sollte der Filter die Eigenschaftenselector
undpredicate
als haben, damit FilterContactList verwendet wird, die automatisch erstellt werden.Erweitern Sie das ein wenig,
Deiner
FilterContactList
würde dann werdenquelle
2[Domain.Model.Entities.Contact,System.Collections.Generic.IEnumerable
1 [System.String]]), Kontakt) konnte nicht analysiert werden. Any (Wert (System.Func`2 [System.String, System .Boolean])) ': Objekt vom Typ' System.Linq.Expressions.ConstantExpression 'kann nicht in den Typ' System.Linq.Expressions.LambdaExpression 'konvertiert werden. Wenn Sie versucht haben, einen Delegaten anstelle eines LambdaExpression zu übergeben, wird dies nicht unterstützt, da Delegaten keine analysierbaren Ausdrücke sind.Ich denke, ein einfacher Weg, dies zu tun, wäre, eine Karte mit Eigenschaftsnamen für Func zu erstellen:
z.B
Und ändern Sie Ihren Code in:
Sie können den Schalter auch ganz entfernen, indem Sie eine Suche nach der passenden Funktion erstellen:
Also, um alles zusammenzufassen:
NB - Ist es nicht redundant, c.FirstName zu überprüfen, wenn Sie auch prüfen (c.FirstName + "" c.LastName)?
quelle
System.InvalidCastException Unable to cast object of type 'NHibernate.Hql.Ast.HqlParameter' to type 'NHibernate.Hql.Ast.HqlBooleanExpression'.