2008-12-17 49 views
2

我希望能够在linq表达式中重构出OrderBy子句。重构OrderBy表达式

这里是其中子句的

前一重构的一个示例:

results = ctx.ActiveUsers 
    .Where(u => u.CompanyID != 1 && 
      (u.LastName.ToLower().Contains(searchString) 
      || u.Email.ToLower().Contains(searchString) 
      || u.Company.Name.ToLower().Contains(searchString))) 
    .OrderBy(u => u.LastName).ThenBy(u => u.FirstName) 
    .Select(u => new Employee { 
     ID = u.ID 
     , FirstName = u.FirstName 
     , LastName = u.LastName 
     , Email = u.Email 
     , CompanyName = u.Company.Name 
     , CompanyID = u.CompanyID.ToString() }); 

后:

results = ctx.ActiveUsers 
    .Where(Employee.GetExpression(searchString)) 
    .OrderBy(u => u.LastName).ThenBy(u => u.FirstName) 
    .Select(u => new Employee { 
     ID = u.ID 
     , FirstName = u.FirstName 
     , LastName = u.LastName 
     , Email = u.Email 
     , CompanyName = u.Company.Name 
     , CompanyID = u.CompanyID.ToString() }); 

private static Expression<Func<User, bool>> GetExpression(string searchString) 
{ 
    Expression<Func<User, bool>> p = (u => u.CompanyID != 1 && 
         (u.LastName.ToLower().Contains(searchString) 
         || u.Email.ToLower().Contains(searchString) 
         || u.Company.Name.ToLower().Contains(searchString))); 
    return p; 
} 

我在想,除非我想重构Orderby表达式,否则我想知道是否可以使用相同类型的东西。

预先感谢您

+0

你需要给你想要什么样的重构的一个例子。我可以看到你为一个searchString做了什么,但是一个排序并不是那样的...... – 2008-12-17 16:00:52

回答

3

假设你想实际采取一个字符串,如“姓氏”,“名字”等,我会做一些事情,如:

var unordered = ctx.ActiveUsers 
        .Where(Employee.GetExpression(searchString)) 
        .OrderBy(ordering) 
        .Select(u => new Employee { 
         ID = u.ID, 
         FirstName = u.FirstName, 
         LastName = u.LastName, 
         Email = u.Email, 
         CompanyName = u.Company.Name, 
         CompanyID = u.CompanyID.ToString() }); 

,并添加了新的排序依据扩展方法:

public static class UserQueryableExtensions 
{ 
    public static IOrderedQueryable<User> OrderBy(this IQueryable<User> source, 
                string ordering) 
    { 
     switch (ordering) 
     { 
      case "LastName": 
       return source.OrderBy(x => x.LastName); 
      case "FirstName": 
       return source.OrderBy(x => x.FirstName); 
      case "Email": 
       return source.OrderBy(x => x.Email); 
      case "Company": 
       return source.OrderBy(x => x.Company); 
      default: 
       throw new ArgumentException("Unknown ordering"); 
     } 
    } 
} 

你当然可以这个使用反射,但除非你有显著的一组属性(或你想对不同的实体类型使用相同的例程),switch语句更容易。

0

我同意Jon在可能的情况下使用lambda来避免错别字等等。但是,如果你真的无法做到这一点(无论什么原因),我已经看过去完全动态的OrderBy。有关在LINQ-to-SQL上测试的示例,请参阅here(但在理论上应该可以使用EF)。

1

感谢乔恩,

这个答案让我在正确的道路上,现在......不过,我 需要保存ThenBy子句中我的订单。因此,虽然下面的解决方案是不动它仍然保留了ThenBy

var unordered = ctx.ActiveUsers 
        .Where(Employee.GetExpression(searchString)) 
        .MyOrder() 
        .Select(u => new Employee { 
         ID = u.ID, 
         FirstName = u.FirstName, 
         LastName = u.LastName, 
         Email = u.Email, 
         CompanyName = u.Company.Name, 
         CompanyID = u.CompanyID.ToString() }); 

public static class UserQueryableExtensions 
{ 
    public static IOrderedQueryable<User> MyOrder(this IQueryable<User> source) 
    { 
     return source.OrderBy(x => x.LastName).ThenBy(x => x.FirstName).ThenBy(x => x.Email); 
    } 
}