[linq] 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통화.

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

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를 여러 개 사용해서는 안됩니다. ThenBy는 OrderBy 이후에 수행되므로 더 안전합니다.


답변