【问题标题】:refactoring the OrderBy expression重构 OrderBy 表达式
【发布时间】:2008-12-17 15:56:20
【问题描述】:

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

这里是一个重构where子句的例子

之前:

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 表达式之外,是否可以使用相同类型的东西。

提前谢谢你

【问题讨论】:

  • 你需要举例说明你想要什么样的重构。我可以看到你为 searchString 做了什么,但排序并不是那样的......

标签: c# linq lambda


【解决方案1】:

假设您实际上想要使用“LastName”、“FirstName”等字符串,我会执行以下操作:

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() });

并添加一个新的 OrderBy 扩展方法:

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 语句会更容易。

【讨论】:

    【解决方案2】:

    谢谢乔恩,

    这个答案让我现在走上了正确的道路......但是, 我需要在我的订单中保留 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);
        }
    }
    

    【讨论】:

      【解决方案3】:

      我同意 Jon 的观点,即尽可能使用 lambdas 以避免拼写错误等。但是,如果您真的不能这样做(无论出于何种原因),我过去曾看过完全动态的 OrderBy。有关在 LINQ-to-SQL 上测试的示例,请参阅 here(但理论上应该可以使用 EF)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-17
        相关资源
        最近更新 更多