Crea IQueryable.Any con Expression Trees per le query LINQ

c# expression-trees

Domanda

Sto costruendo una clausola SQL "WHERE" usando la classe System.Linq.Expressions.Expression. Funziona bene per le clausole semplici, ad esempio per aggiungere la clausola "PhaseCode = X", faccio quanto segue:

var equalTarget = Expression.Constant(phaseCode, typeof(int?));
var phaseEquals = Expression.Equal(Expression.PropertyOrField(projParam, "PhaseCode"), equalTarget);

Tuttavia, ora sto cercando di creare un'espressione che restituirà il record se un progetto è stato assegnato a un particolare gruppo. Project and Group ha una relazione molti-a-molti. Senza gli alberi di espressione, lo farei come segue:

db.Projects.Where(p => .... && p.GroupsAssigned.Any(g => g.ID == groupId))

Tuttavia, non riesco a trovare un modo per esprimerlo con la classe Expression. Ci sono in realtà due cose che non riesco a capire:

  • Come attraversare le relazioni tra i tavoli
  • Come fare x.Any ()

Qualsiasi aiuto è molto apprezzato.

Risposta accettata

Chiamare un metodo di estensione, come Enumerable.Any o Queryable.Any , è semplicemente una chiamata al metodo statico sulla sequenza e l'espressione lambda creata per la clausola WHERE . È possibile utilizzare Expression.Call per fare questo:

// for Enumerable.Any<T>(IEnumerable<T>,Predicate<T>)
var overload = typeof(Enumerable).GetMethods("Any")
                                 .Single(mi => mi.GetParameters().Count() == 2);
var call = Expression.Call(
    overload,
    Expression.PropertyOrField(projParam, "GroupsAssigned"),
    anyLambda);      

Per Queryable.Any<T> , devi Queryable.Any<T> in un metodo:

static Expression BuildAny<TSource>(Expression<Func<TSource, bool>> predicate)
{
    var overload = typeof(Queryable).GetMethods("Any")
                              .Single(mi => mi.GetParameters().Count() == 2);
    var call = Expression.Call(
        overload,
        Expression.PropertyOrField(projParam, "GroupsAssigned"),
        predicate);   

    return call;
}

Anche se questo sembra strano, non sei in grado di farlo attraverso una normale query.



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é