Frage

Ich möchte Filtersteuerungen schreiben, die den Objekttyp einnehmen T und Eigenschaftsname und Rückgabe Expression<Func<T, bool>> Dieser prüft den Wert der übergebenen Eigenschaft. Ich möchte keine Reflexion verwenden, weil ich befürchte, dass solche Ausdrücke von EF nicht verwendet werden können. Ich kann Delegierte nicht verwenden, da C# keine Delegierten für Eigenschaften hat. Was kann ich machen? Vielleicht sollte ich einen anderen Ansatz zum Schreiben dieser Kontrollen verwenden?

Hier ist mein erster Ansatz mit Reflexion:

public string FilteringField { get; set; }
public Expression<Func<T, bool>> GetFilterExpression()
{
  if (cmbValue.SelectedIndex == 1)
    return (o => (bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
  if (cmbValue.SelectedIndex == 2)
    return (o => !(bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
  return null;
}
War es hilfreich?

Lösung

Reflexion ist hier kein Problem. EF kann den Unterschied nicht einmal bemerken. Der Delegate-Ansatz ist übrigens ein Nichtstarter (da Sie EF erwähnen); Letztendlich ist es so etwas wie:

public static IQueryable<T> Where<T>(this IQueryable<T> query,
    string propertyName, object value)
{
    PropertyInfo prop = typeof(T).GetProperty(propertyName);
    var param = Expression.Parameter(typeof(T), "x");
    var body = Expression.Equal(
        Expression.Property(param, prop),
        Expression.Constant(value, prop.PropertyType)
        );
    var predicate = Expression.Lambda<Func<T, bool>>(body, param);
    return query.Where(predicate);
}

Beachten Sie, dass Sie es einfacher machen können Expression.PropertyOrField(propertyName); Der Grund, warum ich das hier nicht benutzt habe, ist, dass es sehr praktisch ist, das Mitgliedstyp zu kennen (prop.PropertyType) Beim Erstellen der Konstante - sonst können Sie Probleme mit Nulls bekommen.

Andere Tipps

Ich kenne das eine alte Antwort, aber wenn jemand das sieht, habe ich dieses Projekt gebaut:

https://github.com/poweredsoft/dynamiclinq

Das sollte auch auf Nuget heruntergeladen werden:

https://www.nuget.org/packages/poweredsoft.dynamiclinq

Und du könntest es einfach tun

query.Where("FirstName", ConditionOperators.Equal, "David");
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top