Je crée une source de données fictive que je veux pouvoir transmettre dans une liste de SortExpressions.Comment utiliser linq pour trier plusieurs champs?
public SortExpression(string name, SortDirection direction)
{
this.name = name;
this.direction = direction;
}
Mise à jour avec le code de Jon Skeet et aussi toute la classe. GetData() remplit simplement l'objet avec x nombre d'enregistrements.
public class Data
{
public int Id { get; set; }
public Guid gId { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public DateTime Created { get; set; }
public string SortMe { get; set; }
public static List<Data> GetFakeData(int start, int numberToFetch, IList<SortExpression> sortExpressions, IList<FilterExpression> filterExpressions, out int totalRecords)
{
DataCollection items = GetData();
IEnumerable<Data> query = from item in items select item;
bool sortExpressionsExist = sortExpressions != null;
if (sortExpressionsExist)
{
// Won't be read in the first iteration; will be written to
IOrderedEnumerable<Data> orderedQuery = null;
for (int i = 0; i < sortExpressions.Count; i++)
{
// Avoid single variable being captured: capture one per iteration.
// Evil bug which would be really hard to find :)
int copyOfI = i;
// Tailor "object" depending on what GetProperty returns.
Func<Data, object> expression = item =>
item.GetType().GetProperty(sortExpressions[copyOfI].Name);
if (sortExpressions[i].Direction == SortDirection.Ascending)
{
orderedQuery = (i == 0) ? query.OrderBy(expression)
: orderedQuery.ThenBy(expression);
}
else
{
orderedQuery = (i == 0) ? query.OrderByDescending(expression)
: orderedQuery.ThenByDescending(expression);
}
}
query = orderedQuery;
}
bool filterExpressionsExist = filterExpressions != null;
if (filterExpressionsExist)
{
foreach (var filterExpression in filterExpressions)
{
query.Where(item => item.GetType().GetProperty(filterExpression.ColumnName).GetValue(item, null).ToString().Contains(filterExpression.Text));
}
}
totalRecords = query.Count();
return query.Skip(start).Take(numberToFetch).ToList<Data>();
}
}
Ne semble pas faire quoi que ce soit. Compile, pas d'erreur, juste pas de tri. Des idées?
Ouais, c'est la raison pour laquelle je fais la boucle au lieu du foreach, parce que je pensais que j'avais besoin d'un ThenBy là-bas quelque part. – rball
Je viens de corriger un bug, d'ailleurs - vous avez besoin de la partie copyOfI sinon la mauvaise variable sera capturée! –
Crap, ne fonctionne toujours pas. – rball