Come eseguire dynamicmente più ordinamenti Linq to Entities

Quindi il mio problema è così; nel codice C #, ho bisogno di eseguire più ordini di un insieme di entity framework con l’aiuto di Linq alle Entità, a seconda dei parametri di input. Ci sono tre colonne su cui ordinare, e l’ordine delle colonne di ordinamento è esso stesso variabile (nel senso che per ogni ordinamento, ho bisogno di cercare su quale colonna ordinare). Come posso raggiungere questo objective?

Ho un codice che dovrebbe funzionare, ma mi ripeto troppo perché non sono stato in grado di parametrizzare le mie operazioni (Linq to Entities è molto restrittivo, cosa posso fare nei miei lambda). Si prega di suggerire come posso riscrivere il mio codice in conformità con il principio di DRY , forse con l’aiuto della generazione del codice T4?

Il seguente codice dovrebbe illustrare il mio problema. È un estratto del codice reale, per brevità, fammi sapere se dovrei includere di più. La variabile orderSpecs è un array di “specifiche dell’ordine”, ognuna delle quali specifica una colonna su cui ordinare e se ordinare in modo discendente. L’array orderSpecs ha almeno un elemento, quindi viene eseguito almeno un ordine.

 using (var db = new MyContainer()) { var orderSpec = orderSpecs[0]; IQueryable dVersions = null; if (orderSpec.Column == 0) { if (orderSpec.Descending) { dVersions = db.Versions.OrderByDescending(ver => ver.Name); } else { dVersions = db.Versions.OrderBy(ver => ver.Name); } } else if (orderSpec.Column == 1) { if (orderSpec.Descending) { dVersions = db.Versions.OrderByDescending(ver => ver.Built); } else { dVersions = db.Versions.OrderBy(ver => ver.Built); } } else if (orderSpec.Column == 2) { if (orderSpec.Descending) { dVersions = db.Versions.OrderByDescending(ver => ver.Id); } else { dVersions = db.Versions.OrderBy(ver => ver.Id); } } foreach (var spec in orderSpecs.Skip(1)) { if (spec.Column == 0) { if (spec.Descending) { dVersions = dVersions.ThenByDescending(ver => ver.Name); } else { dVersions = dVersions.ThenBy(ver => ver.Name); } } else if (spec.Column == 1) { if (spec.Descending) { dVersions = dVersions.ThenByDescending(ver => ver.Built); } else { dVersions = dVersions.ThenBy(ver => ver.Built); } } else if (spec.Column == 2) { if (spec.Descending) { dVersions = dVersions.ThenByDescending(ver => ver.Id); } else { dVersions = dVersions.ThenBy(ver => ver.Id); } } } 

Che dire creare un dizionario per mappare queste colonne che stanno causando questi enormi costrutti if-else alle proprietà. Potrebbe assomigliare a questo:

 using (var db = new MyContainer()) { var orderSpec = orderSpecs[0]; IQueryable dVersions = null; var mapping = new Dictionary>() { { 0, ver => ver.Name }, { 1, ver => ver.Built }, { 2, ver => ver.Id } }; if (orderSpec.Descending) dVersions = db.Versions.OrderByDescending(mapping[orderSpec.Column]); else dVersions = db.Versions.OrderBy(mapping[orderSpec.Column]); foreach (var spec in orderSpecs.Skip(1)) { if (spec.Descending) dVersions = dVersions.ThenByDescending(mapping[spec.Column]); else dVersions = dVersions.ThenBy(mapping[spec.Column]); } } 

Per Untype : puoi anche fare uso di Dynamic Linq Library: Uso della libreria di query dynamic LINQ

inserisci la descrizione dell'immagine qui

O

Articolo completo: Gestisci GridView.OnSorting () e crea dynamicmente l’espressione di ordinamento usando LINQ

Per digitato : puoi eseguire l’ordinamento dinamico come sotto che rimuove il codice che hai scritto

Come eseguire il soring sulla class chiamata person dove il nome della colonna e la direzione di smistamento non sono risolti

 IEnumerable persons = GetPersons(); persons = persons.OrderBy(e.SortExpression, e.SortDirection); 

Classe di persone

 class Person { public string FirstName { get; set; } public string LastName { get; set; } } 

Metodo generico con albero delle espressioni per l’ordinamento dei dati

 public static IEnumerable OrderBy(this IEnumerable collection, string columnName, SortDirection direction) { ParameterExpression param = Expression.Parameter(typeof(T), "x"); // x Expression property = Expression.Property(param, columnName); // x.ColumnName Func func = Expression.Lambda>( // x => x.ColumnName Expression.Convert(Expression.Property(param, columnName), typeof(object)), param).Compile(); Func, Func, IEnumerable> expression = SortExpressionBuilder.CreateExpression(direction); IEnumerable sorted = expression(collection, func); return sorted; }