如何让用户选择如何使用变量对其列表进行排序?

用户输入的信息可以按升序和降序的多种方式排序,我试图让用户选择他想要查看数据的方式:

那么有没有办法设置一个变量,用户输入和排序数据,而不是多次重复代码,具体取决于输入,如:

var empName = el.Select(i => new { i.ID, i.FullName }); if(emsort.Text="text1") empName.OrderBy(i.text1); else if... 

通过做一些更短的事情:

  string sort=emsort.Text ; empName.OrderBy(sort); 

如果您的问题中的用户是某个调用您的函数的软件,那么用户就会知道el序列中对象的类型:他知道el序列中的元素是哪些属性,并且他知道他希望如何订购它们。

为什么不让这个用户给你在keySelector中使用的keySelector

创建扩展function:

 static class QueryableExtensions { IQueryable SelectAndSort(this IQueryable> selector, Expression> sortKeySelector, System.ComponentModel.ListSortDirection sortDirection) { var selectBeforeOrdering = myRepository.el.Select(selector); // note: this is still an IQueryable, only the query has been made, // the database is not accessed yet! IQueryable result = (sortDirection == ListSortDirectrion.Ascending) ? // sort in ascending order: selectBeforeOrdering.OrderBy(sortKeySelector) : // else: selec in descending order: selectBeforeOrdering.OrderByDescending(sortKeySelector); return result; } } 

用法:假设您的用户知道您的el ,并且他想要几个字段,按照您的el某个属性排序

 using (var myDbContext = new DbContext(...)) { IQueryable myEls = myDbContext.el; var mySelectedItems = myEls.SelectAndSore( // selector: what properties do I as a user want? el => new { Id = el.Id, FullName = el.FullName, ... // other desired properties }, // sortSelector: how do I want my selected items to be sorted? selectedItem => selectedItem.FullName, // direction: ListSortDirection.Descending); // note: until now the database has not been accessed // only the Expression of the query has been created. // depending on what you want as a result: ToList / ToArray / First / ... return mySelectedItems.ToList(); } 

另一方面,如果您的用户不是软件,而是操作员,他必须选择他希望订购项目的列,他必须有一种方法告诉计算机应该对哪个列进行排序。

这通常通过单击列来完成。 另一种方法可以是在combobox中选择一个值。 无论如何,您必须将某些内容附加到列或包含sortKeySelector的combobox值:

 class MySortableColumn : DataGridViewColumn // or whatever column class you are using { public Expression> SortKeySelector{get;set;} } 

现在,您有几个列,每个列都显示MyDisplayedItem的一个属性:

 var columnId = new MySortableColumn() { SortKeySelector = displayedItem => myDisplayedItem.Id, }; var columnFullName = new MyStortableColumn() { SortKeySelector = displayedItem => myDisplayedItem.Id, } // etc. 

每当操作员单击一列时,都会提取sortKey并将其用作参数来对项目进行排序:

 void SortColumn(SortableColumn column) { var sortedItems = Sort(column.SortKeySelector, ListSortOrder...); Display(sortedItems); } 

如果我理解你的问题,你想要使用存储在emsort.Text的属性名称动态排序,那么你可以使用表达式:

假设empNameIEnumerable ,那么使用:

 private static Func GetSortable(string sortablePoperty) { var param = Expression.Parameter(typeof(Employee), "e"); var member = Expression.Property(param, sortablePoperty); Expression memberAsObject = Expression.Convert(member, typeof(object)); return Expression.Lambda>(memberAsObject, param).Compile(); } 

然后使用它:

 string sort=emsort.Text ; empName.OrderBy(GetSortable(sort)); 

如果empNameIQueryable ,那么使用:

 private static Expression> GetSortable(string sortablePoperty) { var param = Expression.Parameter(typeof(Employee), "e"); var member = Expression.Property(param, sortablePoperty); Expression memberAsObject = Expression.Convert(member, typeof(object)); return Expression.Lambda>(memberAsObject, param); } 

正如我所假设的, el已实现(例如,它不仅仅是数据库的入口点),因此您可以使用reflection:

 var sort = emsort.Text; PropertyInfo property = null; var sortedData = el.Select(i => new { i.ID, i.FullName }) .OrderBy(x => { property = property ?? x.GetType().GetProperty(sort); return property.GetValue(x); }).ToList(); 

这是我必须写的代码的一部分:

 if (emord.Text == "Ascending") { if (emsort.Text == "ID") { var empName = el.Select(i => new { i.ID, i.FullName }).OrderBy(x => x.ID); var empNamenAmp = el.Select(i => new { i.ID, i.FullName, i.Salary, i.Currency, i.Per }).OrderBy(x => x.ID); var empNamenAmpnwh = el.Select(i => new { i.ID, i.FullName, i.Salary, i.Currency, i.Per, i.Hours }).OrderBy(x => x.ID); var empNamenwh = el.Select(i => new { i.ID, i.FullName, i.Hours }).OrderBy(x => x.ID); var empNamenbd = el.Select(i => new { i.ID, i.FullName, i.Date }).OrderBy(x => x.ID); var empNamenad = el.Select(i => new { i.ID, i.FullName, i.Location }).OrderBy(x => x.ID); var empNamenpn = el.Select(i => new { i.ID, i.FullName, i.PhoneNb }).OrderBy(x => x.ID); var empNamena = el.Select(i => new { i.ID, i.FullName, i.Age }).OrderBy(x => x.ID); if (empfilcomb.Text == "Name") { dispfil.Clear(); foreach (var x in empName) dispfil.Text += x.ID + ", " + x.FullName + Environment.NewLine; } else if (empfilcomb.Text == "Name and Amount paid") { dispfil.Clear(); foreach (var x in empNamenAmp) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Salary + " " + x.Currency + " " + x.Per + Environment.NewLine; } else if (empfilcomb.Text == "Name and Work Hours") { dispfil.Clear(); foreach (var x in empNamenwh) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Hours + Environment.NewLine; } else if (empfilcomb.Text == "Name,Amount paid and Work Hours") { dispfil.Clear(); foreach (var x in empNamenAmpnwh) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Salary + " " + x.Currency + " " + x.Per + ", " + x.Hours + Environment.NewLine; } else if (empfilcomb.Text == "Name and Birthday") { dispfil.Clear(); foreach (var x in empNamenbd) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Date + Environment.NewLine; } else if (empfilcomb.Text == "Name and Address") { dispfil.Clear(); foreach (var x in empNamenad) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Location + Environment.NewLine; } else if (empfilcomb.Text == "Name and Phone Number") { dispfil.Clear(); foreach (var x in empNamenpn) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.PhoneNb + Environment.NewLine; } else if (empfilcomb.Text == "Name and Age") { dispfil.Clear(); foreach (var x in empNamena) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Age + Environment.NewLine; } } else if (emsort.Text == "Name") { var empName = el.Select(i => new { i.ID, i.FullName }).OrderBy(x => x.FullName); var empNamenAmp = el.Select(i => new { i.ID, i.FullName, i.Salary, i.Currency, i.Per }).OrderBy(x => x.FullName); var empNamenAmpnwh = el.Select(i => new { i.ID, i.FullName, i.Salary, i.Currency, i.Per, i.Hours }).OrderBy(x => x.FullName); var empNamenwh = el.Select(i => new { i.ID, i.FullName, i.Hours }).OrderBy(x => x.FullName); var empNamenbd = el.Select(i => new { i.ID, i.FullName, i.Date }).OrderBy(x => x.FullName); var empNamenad = el.Select(i => new { i.ID, i.FullName, i.Location }).OrderBy(x => x.FullName); var empNamenpn = el.Select(i => new { i.ID, i.FullName, i.PhoneNb }).OrderBy(x => x.FullName); var empNamena = el.Select(i => new { i.ID, i.FullName, i.Age }).OrderBy(x => x.FullName); if (empfilcomb.Text == "Name") { dispfil.Clear(); foreach (var x in empName) dispfil.Text += x.ID + ", " + x.FullName + Environment.NewLine; } else if (empfilcomb.Text == "Name and Amount paid") { dispfil.Clear(); foreach (var x in empNamenAmp) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Salary + " " + x.Currency + " " + x.Per + Environment.NewLine; } else if (empfilcomb.Text == "Name and Work Hours") { dispfil.Clear(); foreach (var x in empNamenwh) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Hours + Environment.NewLine; } else if (empfilcomb.Text == "Name,Amount paid and Work Hours") { dispfil.Clear(); foreach (var x in empNamenAmpnwh) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Salary + " " + x.Currency + " " + x.Per + ", " + x.Hours + Environment.NewLine; } else if (empfilcomb.Text == "Name and Birthday") { dispfil.Clear(); foreach (var x in empNamenbd) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Date + Environment.NewLine; } else if (empfilcomb.Text == "Name and Address") { dispfil.Clear(); foreach (var x in empNamenad) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Location + Environment.NewLine; } else if (empfilcomb.Text == "Name and Phone Number") { dispfil.Clear(); foreach (var x in empNamenpn) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.PhoneNb + Environment.NewLine; } else if (empfilcomb.Text == "Name and Age") { dispfil.Clear(); foreach (var x in empNamena) dispfil.Text += x.ID + ", " + x.FullName + ", " + x.Age + Environment.NewLine; } } 

我问是否有一个更短的方法来做:我可以使用的东西。 似乎没有,但非常感谢帮助,我确定你们提供的是有用的。