Как сохранить ссылку на лямбда-выражение, которое позже будет передано в функции OrderBy или LoadWith? - PullRequest
3 голосов
/ 09 декабря 2011

Я пытаюсь создать общий метод доступа к БД. Это будет подразумевать такие параметры, как: индекс страницы, количество элементов, отображаемых на странице, параметры заказа, параметры загрузки и т. Д.

...

public IQuerable<T> GetAll(int pageIndex, int itemsToDisplayPerPage, System.Linq.Expressions.Expression<Func<T,object>>[] orderBy, System.Linq.Expressions.Expression<Func<T,object>>[] loadOptions)
{
  DataContext dc = null;
  IQuerable<T> result = null;
  // Make some initalizations
  ...
  foreach(var item in orderBy)
  {
    result = result.OrderBy(item);
  }

  System.Data.Linq.DataLoadOptions loadOptions = new System.Data.Linq.DataLoadOptions();
  foreach(var item in loadOptions)
  {
    loadOptions.LoadWith(item);
  }
  ...
}

...

Проблема в том, что тип System.Linq.Expressions.Expression< Func< T,object > > не является хорошим общим представлением лямбда-выражения, которое будет передано в обоих приведенных выше примерах.

При заказе произойдет сбой из-за типа объекта, который не имеет никакого смысла для упорядочивания. Также на нагрузке не будет работать. Так что я не знаю, как я могу справиться с этой проблемой. Какие-либо предложения? Спасибо.

1 Ответ

0 голосов
/ 09 декабря 2011

Не уверен насчет LoadWith, так как мы используем linq для сущностей, но мы успешно получили распоряжение работать в методе Get репозитория.Код клиента выглядит следующим образом:

var results = _repository.GetAll(
    new GetAllCriteria()
        .OrderBy(x => x.Property1)
        .OrderBy(x => x.Property2)
);

Мы пока не используем обобщенные элементы в методах репозитория, которые, вероятно, появятся в будущем рефакторе.Но реализация критериев выглядит следующим образом:

public class GetAllCriteria
{
    public Dictionary<Expression<Func<CustomType, object>>, bool> ToBeOrderedBy 
    { 
        get; private set;
    }

    public GetAllCriteria OrderBy(
        Expression<Func<CustomType, object>> expression)
    {
        return OrderBy(expression, true);
    }

    public GetAllCriteria OrderByDescending(
        Expression<Func<CustomType, object>> expression)
    {
        return OrderBy(expression, false);
    }

    private GetAllCriteria OrderBy(
        Expression<Func<CustomType, object>> expression, bool isAscending)
    {
        if (expression != null)
        {
            if (ToBeOrderedBy == null)
                ToBeOrderedBy = new Dictionary<Expression<Func<CustomType, object>>, bool>();
            ToBeOrderedBy.Add(expression, isAscending);
        }
        return this;
    }   
}

Затем репозиторий упорядочивается следующим образом:

public Collection<CustomType> GetAll(GetAllCriteria criteria)
{
    var query = dbContext.CustomTypes.AsQueryable();

    // some code

    // apply order by
    if (criteria.ToBeOrderedBy != null && criteria.ToBeOrderedBy.Count > 0)
    {
        var firstOrderBy = criteria.ToBeOrderedBy.First();
        query = firstOrderBy.Value
            ? query.OrderBy(firstOrderBy.Key)
            : query.OrderByDescending(firstOrderBy.Key);

        query = criteria.ToBeOrderedBy.Skip(1).Aggregate(query, 
            (lastOrderBy, nextOrderBy) => nextOrderBy.Value
            ? ((IOrderedQueryable<CustomType>)lastOrderBy)
                .ThenBy(nextOrderBy.Key)
            : ((IOrderedQueryable<CustomType>)lastOrderBy)
                .ThenByDescending(nextOrderBy.Key));
    }

    // some more code

    var results = query.ToList();
    return results;
}

Если это работает с linq для сущностей, я бы предположил, что оно должно работать с linqдо кв.

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