Sto provando a creare una classe rapida in modo che possa rendere la scrittura del codice di ordinamento per una griglia molto più facile da gestire e mantenere e mantenere la ripetizione del codice verso il basso. Per fare questo mi si avvicinò con la seguente classe:Come è possibile memorizzare dinamicamente le espressioni utilizzate per Linq Orderby?
public class SortConfig<TSource, TRelatedObject> where TSource : class where TRelatedObject : class
{
public IList<SortOption> Options { get; protected set; }
public SortOption DefaultOption { get; set; }
public SortConfig()
{
Options = new List<SortOption>();
}
public void Add(string name, Expression<Func<TSource, object>> sortExpression, TRelatedObject relatedObject, bool isDefault = false)
{
var option = new SortOption
{
FriendlyName = name,
SortExpression = sortExpression,
RelatedObject = relatedObject
};
Options.Add(option);
if (isDefault)
DefaultOption = option;
}
public SortOption GetSortOption(string sortName)
{
if (sortName.EndsWith("asc", StringComparison.OrdinalIgnoreCase))
sortName = sortName.Substring(0, sortName.LastIndexOf("asc", StringComparison.OrdinalIgnoreCase));
else if (sortName.EndsWith("desc", StringComparison.OrdinalIgnoreCase))
sortName = sortName.Substring(0, sortName.LastIndexOf("desc", StringComparison.OrdinalIgnoreCase));
sortName = sortName.Trim();
var option = Options.Where(x => x.FriendlyName.Trim().Equals(sortName, StringComparison.OrdinalIgnoreCase))
.FirstOrDefault();
if (option == null)
{
if (DefaultOption == null)
throw new InvalidOperationException(
string.Format("No configuration found for sort type of '{0}', and no default sort configuration exists", sortName));
option = DefaultOption;
}
return option;
}
public class SortOption
{
public string FriendlyName { get; set; }
public Expression<Func<TSource, object>> SortExpression { get; set; }
public TRelatedObject RelatedObject { get; set; }
}
}
L'idea è di creare una configurazione rapida delle diverse opzioni di ordinamento, quello orderBy espressione è usata per questo, e opzionalmente un oggetto che è legata a quella opzione di ordinamento In questo modo il mio codice a guardare come:
protected void InitSortConfig()
{
_sortConfig = new SortConfig<xosPodOptimizedSearch, HtmlAnchor>();
_sortConfig.Add("name", (x => x.LastName), lnkSortName, true);
_sortConfig.Add("team", (x => x.SchoolName), lnkSortTeam);
_sortConfig.Add("rate", (x => x.XosRating), lnkSortRate);
_sortConfig.Add("pos", (x => x.ProjectedPositions), null);
_sortConfig.Add("height", (x => x.Height), lnkSortHeight);
_sortConfig.Add("weight", (x => x.Weight), lnkSortWeight);
_sortConfig.Add("city", (x => x.SchoolCity), lnkSortCity);
_sortConfig.Add("state", (x => x.SchoolState), lnkSortState);
}
e allora posso ordinare da solo facendo
// Get desired sorting configuration
InitSortConfig();
var sortOption = _sortConfig.GetSortOption(sort);
bool isDescendingSort = sort.EndsWith("desc", StringComparison.OrdinalIgnoreCase);
// Setup columns
InitSortLinks();
if (sortOption.RelatedObject != null)
{
// Make modifications to html anchor
}
// Form query
var query = PodDataContext.xosPodOptimizedSearches.AsQueryable();
if (isDescendingSort)
query = query.OrderByDescending(sortOption.SortExpression);
else
query = query.OrderBy(sortOption.SortExpression);
Questa grande opera quando la variabile ordinata è una stringa, ma quando non è una stringa ottengo la seguente eccezione: Cannot order by type 'System.Object'.
Suppongo che ciò sia dovuto al fatto che sto memorizzando l'espressione come Expression<Func<TSource, object>>
e non essendo più specifico su quel 2 ° generico. Non capisco come posso mantenere tutte le mie diverse opzioni di ordinamento (anche per le proprietà non stringa) in una classe.
Credo che uno dei problemi è che la clausola Linq.OrderBy()
prende Expression<Func<TSource, TKey>>
come è il parametro, ma io non sono il confezionamento mia testa intorno a come Linq.OrderBy()
è in grado di dedurre cosa TKey
dovrebbe essere, e quindi non riesco a capire come approfittare di quella deduzione per memorizzare queste espressioni con l'appropriato TKey
.
Qualche idea?
Date un'occhiata a [questo] (http://weblogs.asp.net/scottgu/archive/2008/01 /07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx) – Nestor
Grazie, ma preferirei che l'ordinamento sia specificato dal codice piuttosto che dalla stringa specificata, soprattutto dal momento che la struttura dei dati del mio la griglia non è un modello di dati 1: 1 con il mio database, quindi l'ordinamento deve essere tradotto dalla griglia specificata in un ordinamento db in ogni caso – KallDrexx
Non stai usando una stringa magica quando ottieni comunque l'opzione di ordinamento? –