订购linq查询
对于我的通用网格,我目前这样做是为了激活排序:
Elements.OrderBy(column.SortExpression).AsQueryable();
其中SortExpression的类型为Func
和column是generics类Column
我在这样的控制器中设置了SortExpression:
new Column{Key = "ShippingDate", SortExpression = e => e.ShippingDate}
‘OrderBy’导致执行sql语句,这是我不想要的。
所以我试图用这个替换它:
Elements = from element in Elements orderby column.SortExpression select element;
哪个不会触发sql执行。
现在,当然column.SortExpression应该是另一种类型。 只有我无法确定它应该是什么类型以及如何在控制器中的generics类上设置它。
我仍然可以使用某种通用的强类型方式设置SortExpression。
有关如何通过表达式在应用程序中的其他位置进行排序的任何建议,而不是在将顺序应用于IQueryable时执行sql?
@Ewwicker:
这有效:
Expression<Func> sortexpression = e => e.BirthDate; var db = new NorthwindDataContext(); var query = from e in db.Employees select e; query = query.OrderBy(sortexpression); int count = query.Count();
并生成:
SELECT COUNT(*) AS [value] FROM [dbo].[Employees] AS [t0]
当我更换DateTime? 在对象的第一行:
Expression<Func> sortexpression = e => e.BirthDate;
我得到一个InvalidOperationException:无法按类型’System.Object’排序
现在,你可能会说:“然后只使用DateTime?”,但我想在我的通用网格中构建列以要求尽可能少的代码。 我不希望人们必须输入整个Expression<Func>
。 我希望人们能够像我的第一次尝试一样输入一些小的东西SortExpression = e => e.BirthDate
,我利用通用的Column类来定义’T’。
你认为有可能创建某种扩展,以某种方式得到e.BirthDate
的类型,然后将Func
为Expression<Func>
? 然后我可以在内部代码中执行一些操作,如:Elements.OrderBy(column.SortExpression.FixCast())
我不太关心我的内部代码目前是丑陋还是复杂。 我需要正确地获取SQL查询,并为使用网格的开发人员提供可用性。
非常感谢帮助我!
@ earwicker 2:
var gridBuilder = new RainbowGridBuilder("Examples_Employees") { Elements = GetEmployees(), //The elements (records) we will show in our grid. //Define the columns for our grid. Columns = new List<Column>{ new Column { Key = "EmployeeId", //Key is used for sorting, selecting columns, ... Header = "Employee Id", //The header of the column. Also used as caption in the column selection checkboxlist. ValueExpression = e => e.EmployeeID.ToString(), //The Linq expression which will be executed on each element to fill the cell SortExpression = e => e.EmployeeID, //The Linq expression by which to sort the elements in the grid. Display = false}, //Is this column visible by default? new Column {Key = "Name", ValueExpression = e => e.FirstName + " " + e.LastName, SortExpression = e => e.LastName}, }, // Some other properties here that are irrelevant. }
SortExpression应为Expression
。
通过使它成为Func
,您可以使编译器将其直接减少到IL,准备执行。 Linq to SQL(或实体,或NHibernate,或其他)将需要以表达式树的forms捕获的代码,以便它可以将其转换为SQL或其他一些查询语言以便在其他地方执行。 通过将lambda分配给Expression
可以触发编译到表达式树。
你把这个放了吗?
Elements = Elements.OrderBy(e => e.ShippingDate);
那怎么样?
Expression> sortExpression = e => e.ShippingDate; Elements = Elements.OrderBy(sortExpression);
根据您更新的问题,听起来您需要捕获具有静态类型返回值的表达式,而不是object
。
很难知道什么是理想的安排,但在您的原始设置代码中,您有:
new Column{Key = "ShippingDate", SortExpression = e => e.ShippingDate}
假设Column
采用了两个类型参数: TElem
(存储在列中的值的种类)和TSort
(要排序的值的类型)。
new Column { SortExpression = e => e.BirthDate }
这对我来说看起来并不太笨重,而SortExpression
则只是:
Expression> SortExpression { get; set; }
我想出了一个解决方案,实现了我的目标。
用法:在列上设置强类型排序表达式:
Columns = new List>{ new Column { Key = "EmployeeId", SortExpression = new SortExpression (e => e.EmployeeID) // ... other irrelevant column properties ... }, new Column { Key = "EmployeeBirthDate", SortExpression = new SortExpression (e => e.BirthDate) } };
基础代码
RainbowGridBuilder类中“buildGrid()”方法中的这几行应用排序:
if (columnToSort != null) //sort the elements according to the set column key and the sortexpression { var column = Columns.Where(c => c.Key == columnToSort).SingleOrDefault(); if (column != null) { Elements = column.SortExpression.ApplySortExpression(Elements, descending); } }
这个怎么运作:
通过在我创建的SortExpression类中使用重载的构造函数,我可以设置一个私有的Expression
。
在SortExpression类中是一个方法ApplySortExpression,它搜索非null私有成员并相应地进行排序:
public class SortExpression { private Expression> DateTimeExpression { get; set; } private Expression> intExpression { get; set; } private Expression> stringExpression { get; set; } public SortExpression(Expression> expression) { DateTimeExpression = expression; } public SortExpression(Expression> expression) { intExpression = expression; } public SortExpression(Expression> expression) { stringExpression = expression; } public IQueryable ApplySortExpression(IQueryable elements, bool? descending) { if (DateTimeExpression != null) { if (descending.HasValue && descending.Value) return elements.OrderByDescending(DateTimeExpression); else return elements.OrderBy(DateTimeExpression); } else if (intExpression != null) { if (descending.HasValue && descending.Value) return elements.OrderByDescending(intExpression); else return elements.OrderBy(intExpression); } else if (stringExpression != null) { if (descending.HasValue && descending.Value) return elements.OrderByDescending(stringExpression); else return elements.OrderBy(stringExpression); } else throw new Exception("Unsuported sortkey type"); } }
这个解决方案在引擎盖下可能不是很干净,但这是我追求的可用性。 消费代码的唯一变化是添加“ new SortExpression
”。
我认为问题的根源是由于您在转换为Queryable 之前执行了OrderBy。 如果您在IEnumerable
这是我对这个orderby问题的简单解决方案:
var SampleData = new SampleDataContext(); var text = from i in SampleData.Events select i; var text2 = text.OrderByDescending(i => i.id); return View(text2);