IT story

LINQ OrderBy와 ThenBy

hot-time 2020. 7. 20. 07:26
반응형

LINQ OrderBy와 ThenBy


누구나 차이점이 무엇인지 설명 할 수 있습니까?

tmp = invoices.InvoiceCollection
              .OrderBy(sort1 => sort1.InvoiceOwner.LastName)
              .OrderBy(sort2 => sort2.InvoiceOwner.FirstName)
              .OrderBy(sort3 => sort3.InvoiceID);

tmp = invoices.InvoiceCollection
              .OrderBy(sort1 => sort1.InvoiceOwner.LastName)
              .ThenBy(sort2 => sort2.InvoiceOwner.FirstName)
              .ThenBy(sort3 => sort3.InvoiceID);

3 가지 데이터 항목으로 주문하려는 경우 올바른 방법은 무엇입니까?


당신은해야 확실히 사용하는 ThenBy여러보다는 OrderBy통화. (귀하의 질문에있는 스 니펫 중 하나가을 (를) 사용하기로되어 있다고 가정합니다 ThenBy.이 글을 쓰는 시점에서 두 스 니펫은 동일합니다.)

나는 이것을 제안 할 것이다 :

tmp = invoices.InvoiceCollection
              .OrderBy(o => o.InvoiceOwner.LastName)
              .ThenBy(o => o.InvoiceOwner.FirstName)
              .ThenBy(o => o.InvoiceID);

매번 같은 이름을 사용하는 방법에 유의하십시오. 이것은 또한 다음과 같습니다.

tmp = from o in invoices.InvoiceCollection
      orderby o.InvoiceOwner.LastName,
              o.InvoiceOwner.FirstName,
              o.InvoiceID
      select o;

OrderBy여러 번 호출 하면 순서가 완전히 세 번 재정렬됩니다 . 따라서 최종 호출은 사실상 지배적입니다. 당신은 할 수 있습니다 (LINQ의 개체) 쓰기

foo.OrderBy(x).OrderBy(y).OrderBy(z)

어느 것이

foo.OrderBy(z).ThenBy(y).ThenBy(x)

정렬 순서가 안정적이지만 절대로해서는 안됩니다.

  • 읽기 어렵다
  • 전체 시퀀스를 재정렬하기 때문에 성능이 좋지 않습니다.
  • 다른 공급자 (예 : LINQ to SQL) 에서는 제대로 작동 하지 않을 수 있습니다.
  • 기본적으로 어떻게 OrderBy사용되도록 설계 되지 않았습니다 .

요점은 OrderBy"가장 중요한"순서 투영법을 제공하는 것입니다. 그런 다음 ThenBy(반복적으로) 2 차, 3 차 등의 순서 투영을 지정하십시오.

효과적으로 다음과 같이 생각 OrderBy(...).ThenBy(...).ThenBy(...)하십시오. 두 객체에 대해 단일 복합 비교를 구축 한 다음 해당 복합 비교를 사용하여 시퀀스를 한 번 정렬 할 수 있습니다. 그것은 거의 확실하게 당신이 원하는 것입니다.


일반적인 방식으로 쿼리를 작성하려고하면이 구별이 성가신 것으로 나타 났으므로 OrderBy / ThenBy를 적절한 순서로 생성하여 원하는만큼 많은 도우미를 만들었습니다.

public class EFSortHelper
{
  public static EFSortHelper<TModel> Create<TModel>(IQueryable<T> query)
  {
    return new EFSortHelper<TModel>(query);
  }
}  

public class EFSortHelper<TModel> : EFSortHelper
{
  protected IQueryable<TModel> unsorted;
  protected IOrderedQueryable<TModel> sorted;

  public EFSortHelper(IQueryable<TModel> unsorted)
  {
    this.unsorted = unsorted;
  }

  public void SortBy<TCol>(Expression<Func<TModel, TCol>> sort, bool isDesc = false)
  {
    if (sorted == null)
    {
      sorted = isDesc ? unsorted.OrderByDescending(sort) : unsorted.OrderBy(sort);
      unsorted = null;
    }
    else
    {
      sorted = isDesc ? sorted.ThenByDescending(sort) : sorted.ThenBy(sort)
    }
  }

  public IOrderedQueryable<TModel> Sorted
  {
    get
    {
      return sorted;
    }
  }
}

유스 케이스에 따라 이것을 사용할 수있는 많은 방법이 있지만, 예를 들어 정렬 열 및 방향 목록을 문자열 및 부울로 전달한 경우 반복하여 다음과 같은 스위치에서 사용할 수 있습니다.

var query = db.People.AsNoTracking();
var sortHelper = EFSortHelper.Create(query);
foreach(var sort in sorts)
{
  switch(sort.ColumnName)
  {
    case "Id":
      sortHelper.SortBy(p => p.Id, sort.IsDesc);
      break;
    case "Name":
      sortHelper.SortBy(p => p.Name, sort.IsDesc);
      break;
      // etc
  }
}

var sortedQuery = sortHelper.Sorted;

결과 sortedQuery는 다른 대답에서주의하는대로 계속 반복되는 대신 원하는 순서로 정렬됩니다.


하나 이상의 필드를 정렬하려면 ThenBy로 이동하십시오.

이처럼

list.OrderBy(personLast => person.LastName)
            .ThenBy(personFirst => person.FirstName)

예, 여러 개의 키로 연주하는 경우 여러 OrderBy를 사용해서는 안됩니다. 그런 다음 OrderBy 후에 수행되므로 베팅이 더 안전합니다.

참고 URL : https://stackoverflow.com/questions/3760001/linq-orderby-versus-thenby

반응형