Espressione personalizzata

c#-4.0 expression-trees linq-to-entities

Domanda

Ho trovato questo codice di esempio:

public IQueryable<T> Get<T>(ObjectSet<T> obj) where T : class
{
    Type type = typeof(T);
    var x = type.GetInterface("IMyInterface");

    if (x != null)
    {
        var property = type.GetProperty("MyStringField");
        var parameter = Expression.Parameter(typeof(T), "it");
        Expression<Func<T, bool>> predicate =
            (Expression<Func<T, bool>>)Expression.Lambda(
                Expression.Equal(
                    Expression.MakeMemberAccess(parameter, property),
                    Expression.Constant("MyValue")),
                parameter);
        //...
    }
}

Quello di cui ho veramente bisogno è applicare una condizione StartsWith ( StartsWith("MyValue") ) e applicare un'altra condizione come> = per il mio altro int? proprietà.

Come posso modificare il codice per fare questo?

Risposta popolare

Prima di tutto, considera quale espressione rappresenta questo albero di espressioni.

var property = type.GetProperty("MyStringField");
var parameter = Expression.Parameter(typeof(T), "it");
Expression<Func<T, bool>> predicate =
    (Expression<Func<T, bool>>)Expression.Lambda(
        Expression.Equal(
            Expression.MakeMemberAccess(parameter, property),
            Expression.Constant("MyValue")),
        parameter);

è equivalente al lambda:

it => it.MyStringField == "MyValue"

Allora, cosa ti piacerebbe che fosse l'espressione? Da quello che ho capito hai scritto, vuoi qualcosa del genere:

it => it.MyStringField.StartsWith("MyValue") && it.MyNullableIntField >= 12

Bene, puoi scrivere questo lambda e memorizzarlo in un'espressione in questo modo puoi lasciare che il compilatore esegua la conversione per te:

Expression<Func<T, bool>> predicate =
    it => it.MyStringField.StartsWith("MyValue") && it.MyNullableIntField >= 12;

Altrimenti, farlo a mano:

var parameter = Expression.Parameter(typeof(T), "it");
var predicate = Expression.Lambda<Func<T, bool>>(
    Expression.AndAlso(
        Expression.Call(
            Expression.Property(parameter, "MyStringField"),
            "StartsWith",
            null,
            Expression.Constant("MyValue")
        ),
        Expression.GreaterThanOrEqual(
            Expression.Property(parameter, "MyNullableIntField"),
            Expression.Convert(Expression.Constant(12), typeof(int?))
        )
    ),
    parameter
);


Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché