对于我的通用网格,我目前这样做是为了激活排序:
Elements.OrderBy(column.SortExpression).AsQueryable();
其中 SortExpression 是
Func<T, object>
类型,column 是一个泛型类 Column<T>
我在这样的 Controller 中设置了 SortExpression:
new Column<OrderViewData>{Key = "ShippingDate", SortExpression = e => e.ShippingDate}
'OrderBy' 导致执行 sql 语句,这是我不想要的。
所以我试图用这个替换它:
Elements = from element in Elements
orderby column.SortExpression
select element;
这不会触发 sql 执行。
现在,当然 column.SortExpression 应该是另一种类型。只有我无法真正弄清楚它应该是什么类型以及如何在 Controller 中的泛型类上设置它。
我应该仍然能够以某种通用的强类型方式设置 SortExpression。
关于如何通过在应用程序中其他地方设置的表达式进行排序,而不在将订单应用于 IQueryable 时执行 sql 的任何建议?
@Earwicker:
这有效:
Expression<Func<Employee, DateTime?>> 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<Employee, object>> sortexpression = e => e.BirthDate;
我收到一个 InvalidOperationException:无法按类型“System.Object”订购
现在,您可能会说:“那么只使用 DateTime?”,但我希望在通用网格中构建列以尽可能减少代码量。我不希望人们必须输入整个
Expression<Func<Employee, some_type>>
。我希望人们能够像我第一次尝试 SortExpression = e => e.BirthDate
那样输入一些小的东西,在那里我利用通用 Column 类来定义“T”。你认为有可能创建某种扩展,以某种方式获取
e.BirthDate
的类型,然后将 Func<T, object>
转换为 Expression<Func<T,some_type>>
吗?然后我可以在内部代码中做一些事情,比如:
Elements.OrderBy(column.SortExpression.FixCast())
我现在不太关心我的内部代码是否丑陋或复杂。我需要正确执行 SQL 查询并注意使用网格的开发人员的可用性。
非常感谢你帮助我!
@earwicker 2:
var gridBuilder = new RainbowGridBuilder<Employee>("Examples_Employees")
{
Elements = GetEmployees(), //The elements (records) we will show in our grid.
//Define the columns for our grid.
Columns = new List<Column<Employee>>{
new Column<Employee> {
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<Employee> {Key = "Name", ValueExpression = e => e.FirstName + " " + e.LastName, SortExpression = e => e.LastName},
},
// Some other properties here that are irrelevant.
}
最佳答案
SortExpression 应该是 Expression<Func<T, object>>
类型。
通过将其设为 Func<T, object>
,您可以让编译器将其直接缩减为 IL,准备执行。 Linq to SQL(或实体,或 NHibernate,或其他)需要以表达式树的形式捕获的代码,以便它可以将其转换为 SQL 或其他一些查询语言,以便在其他地方执行。通过将您的 lambda 分配给 Expression<Func<...>>
,您可以触发对表达式树的编译。
如果你放这个有用吗?
Elements = Elements.OrderBy(e => e.ShippingDate);
这个怎么样?
Expression<Func<OrderViewData, object>> sortExpression = e => e.ShippingDate;
Elements = Elements.OrderBy(sortExpression);
根据您更新的问题,听起来您需要使用静态类型的返回值而不是
object
来捕获表达式。很难知道什么是您的理想安排,但在您的原始设置代码中,您有:
new Column<OrderViewData>{Key = "ShippingDate", SortExpression = e => e.ShippingDate}
假设
Column
有两个类型参数,TElem
(存储在列中的值的类型)和 TSort
(要排序的值的类型)。new Column<Employee, DateTime?> { SortExpression = e => e.BirthDate }
这对我来说看起来不太笨拙,然后
SortExpression
将是:Expression<Func<TElem, TSort>> SortExpression { get; set; }
关于c# - 订购 linq 查询,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/914681/