Ho una variabile denominata sortColumn, che contiene il testo di una colonna con cui voglio ordinare un risultato della query. Ho anche un repository generico che accetta come parametro un'Espressione che contiene il campo che voglio ordinare. Non riesco a passare dal nome della proprietà stringa a un'espressione.Crea espressione generica dal nome della proprietà di stringa
Così il repository generico che ho contiene il seguente metodo di
public IEnumerable<TEntity> Get<TOrderBy>(Expression<Func<TEntity, bool>> criteria,
Expression<Func<TEntity, TOrderBy>> orderBy, int pageIndex,
int pageSize,
bool isAssendingOrder = true,
EnumDeletePolicy deletePolicy = EnumDeletePolicy.ExcludeDeleted)
Avviso il secondo parametro a questo Get è Expression-func-TEntity, TOrderBy. Come ho già detto, ho una variabile chiamata sortColumn, che contiene la stringa per una proprietà sul mio oggetto TEntity. Devo convertire questa stringa in un'espressione che posso passare al metodo Get.
Ecco quello che ho adesso.
var parameter = Expression.Parameter(typeof(IContract));
var memberExpression = Expression.Property(parameter, data.SortColumn);
var lambdaExpression = Expression.Lambda(memberExpression, parameter);
Che crea un oggetto di tipo LambdaExpression. Il tipo effettivo di questa espressione lambda è un Expression-Func-IContract, una stringa (o qualunque sia il tipo sortColumn della proprietà). Se chiamo il metodo Get e passo in LambdaExpression e lo lancio esplicitamente nel tipo Expression, funzionerà correttamente. Il problema è che non so quale sia il tipo di espressione, potrebbe essere una stringa, int, int ?, ecc. Tutto dipende dal tipo di proprietà che è specifica nella proprietà sortColumn.
Puoi aiutarmi a eseguire questo ultimo salto a destra nel tipo di espressione?
Modifica basata sui suggerimenti di Marc: Ho quasi questo funzionamento, in realtà basato specificamente sulla domanda che sta funzionando, ma ho 1 problema rimanente.
L'IContract che è il tipo di entità su cui sto interrogando effettivamente eredita da IRelationship. Se si specifica un campo dall'interfaccia IContract, il codice sopra funziona. Se si specifica un campo dall'interfaccia IRelationship, la seguente riga fallisce.
var memberExpression = Expression.Property(parameter, data.SortColumn);
Se provo qualcosa di simile di seguito in modo che sto afferrando il MemberExpression dal IRelationship, ma la costruzione del Lambda sulla base di IContract ottengo un errore dal repository.
var parameter = Expression.Parameter(typeof(IRelationship));
var memberExpression = Expression.Property(parameter, data.SortColumn);
var orderBy = Expression.Lambda(memberExpression, Expression.Parameter(typeof(IContract)));
L'errore che ottengo è "il parametro '' non è stato rilegato in LINQ to Entities specificato interrogare espressione".
L'espressione finale per farlo funzionare è stato questo
var parameter = Expression.Parameter(typeof(IContract));
var memberExpression = Expression.Property(parameter, typeof(IRelationship), data.SortColumn);
var orderBy = Expression.Lambda(memberExpression, parameter);
quindi avevo bisogno di specificare il parametro centrale per la linea memberExpression, a dire guardare nell'interfaccia relazione ereditato per la proprietà
Che cosa vuoi fare con l'espressione? Ci sono modi per usare 'dynamic' per farlo girare nel sovraccarico generico più appropriato, in pratica evitando' MakeGenericMethod'. Qualche uso? Ad esempio: 'IQueryable filtered = Queryable.Where (source, (dynamic) expression);' –