рефакторинг выражения OrderBy - PullRequest
2 голосов
/ 17 декабря 2008

Я бы хотел иметь возможность рефакторинга предложения OrderBy в выражении linq.

Вот пример рефактора из , где предложение

перед:

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 .

Заранее спасибо

Ответы [ 3 ]

3 голосов
/ 17 декабря 2008

Если вы действительно хотите взять строку, такую ​​как «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 проще.

1 голос
/ 17 декабря 2008

спасибо, Джон,

этот ответ пока что поставил меня на правильный путь ... Однако, Мне нужно сохранить в моем заказе предложение 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);
    }
}
0 голосов
/ 17 декабря 2008

Я бы согласился с Джоном использовать лямбды, где это возможно, чтобы избежать опечаток и т. Д. Однако, если вы действительно не можете этого сделать (по какой-либо причине), я смотрел на полностью динамический OrderBy в прошлом. См. здесь для примера, протестированного на LINQ-to-SQL (но это должно быть хорошо с EF в теории).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...