Создание метода выражения сортировки в Linq - PullRequest
1 голос
/ 23 февраля 2012

Я привел простой пример, который, надеюсь, иллюстрирует мою цель.В настоящее время у меня есть метод, который возвращает своего рода «ранжирование», это не так сложно, но это не переводит в SQL.Производительность ужасна, потому что все это делается в памяти, и я пытаюсь улучшить скорость.

public class Something
{
   DateTime Date {get; set;}
   // ...

   public int SortRank(Sort sort)
   {
     if (sort == Sort.Newest)
     {
       return -Date.Ticks;
     {
     else if (sort == sort.Oldest)
     {
       return Date.Ticks;
     }
   }
}

enum Sort
{
  Newest,
  Oldest
}

using (Context db = new Context()
{
  var q = db.GetTable<Something>()
            .OrderBy(x=> x.SortRank(Sort.Newest));
}

SortRank() в настоящее время не имеет перевода на SQL, поэтому я хотел бы преобразовать его в выражениетак что это может быть оценено в базе данных.Каков наилучший способ сделать это?И да, я знаю, что мог бы просто реализовать эту строку в анонимной лямбде, но меня больше интересует, как сгенерировать выражение.

1 Ответ

1 голос
/ 24 февраля 2012

Я бы посоветовал, так как другие предлагают создать IOrderedQueryable.Создать выражение (особенно такое, как у вас выше) довольно легко.Вы можете посмотреть на параметр для OrderBy, чтобы получить представление о том, как его создать, и он будет выглядеть примерно так:

Expression<Func<Something, Date>> sortExpression = t => t.Date;

Тогда вы можете использовать его вот так db.GetTable<Something>().OrderBy(sortExpression).Таким образом, вы можете увидеть, как довольно легко создавать различные выражения сортировки.Тем не менее, я все еще думаю, что что-то, где вы создаете IOrderedQueryable, является самым чистым и даст лучший SQL-запрос.

public IOrderedQueryable<Something> SortRank(IQueryable<Something> query, Sort sort)
{
    Expression<Func<Something, DateTime>> sortExpression = t => t.Date;

    if (sort == Sort.Newest)
    {
        return query.OrderByDescending(sortExpression);
    }
    else
    {
        return query.OrderBy(sortExpression);
    }
}

вы можете даже изменить подпись на

public static IOrderedQueryable<Something> SortRank(this IQueryable<Something> query, Sort sort) 

и использоватьэто как метод расширения.

Затем вы можете назвать его так:

using (Context db = new Context() 
{ 
    var q = SortRank(db.GetTable<Something>(), Sort.Newest); 
    //Extension method version
    var q = db.GetTable<Something>().SortRank(Sort.Newest);
} 

Другой вариант - создать деревья выражений, которые переводят ваше перечисление непосредственно в запрос, однако это более сложный процесс.и я уверен, что вы можете найти отличную информацию о них в Google и SO.

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