두 개의 테이블이 movies
있으며 먼저 categoryIDcategories
로 정렬 한 다음 Name 별로 정렬 된 목록을 얻습니다 .
영화 테이블에는 ID와 Name 이라는 세 개의 열이 있습니다. 카테고리 테이블에는 ID 및 Name의 두 열이 있습니다.
나는 다음과 같은 것을 시도했지만 작동하지 않았다.
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
두 개의 테이블이 movies
있으며 먼저 categoryIDcategories
로 정렬 한 다음 Name 별로 정렬 된 목록을 얻습니다 .
영화 테이블에는 ID와 Name 이라는 세 개의 열이 있습니다. 카테고리 테이블에는 ID 및 Name의 두 열이 있습니다.
나는 다음과 같은 것을 시도했지만 작동하지 않았다.
var movies = _db.Movies.OrderBy( m => { m.CategoryID, m.Name })
답변:
이것은 당신을 위해 작동해야합니다 :
var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)
Var movies = _db.Movies.Orderby(c => c.Category).ThenBy(n => n.Name)
사용하는 대신 Var movies = _db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
결과가 다른 이유는 무엇입니까?
ThenBy
습니까?! ( 편집 : .NET 4.0에서 소개 된 것처럼 보이며 눈에 띄지 않게 미끄러졌습니다.)
람다가 아닌 쿼리 구문 LINQ를 사용하여 다음을 수행 할 수 있습니다.
var movies = from row in _db.Movies
orderby row.Category, row.Name
select row;
[주석을 수정하려면 편집] 정렬 순서를 제어하려면 키워드 ascending
(기본적으로 유용하지는 않지만) 또는을 사용하십시오 descending
.
var movies = from row in _db.Movies
orderby row.Category descending, row.Name
select row;
_db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
. 더 정확한 것은from row in _db.Movies orderby row.Category descending orderby row.Name select row
_db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
합니다. 제공하는 두 스 니펫은 OP가 아닌 서로 동일합니다.
새로운 걸 더하다":
var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })
그것은 내 상자에서 작동합니다. 정렬하는 데 사용할 수있는 것을 반환합니다. 두 개의 값을 가진 객체를 반환합니다.
다음과 같이 유사하지만 결합 된 열을 기준으로 정렬하는 것과 다릅니다.
var movies = _db.Movies.OrderBy( m => (m.CategoryID.ToString() + m.Name))
.OrderBy( m => new { m.CategoryID, m.Name })
및 .OrderBy( m => new { m.Name, m.CategoryID })
의도 우선 순위를 존중하기보다는 동일한 결과를 생성합니다. 때로는 우연의 일치로 원하는 순서를 제시하는 것처럼 보일 것입니다. 또한 m.CategoryID.ToString() + m.Name
CategoryID가 인 경우 잘못된 주문이 생성됩니다 int
. 예를 들어, id = 123, name = 5times 인 항목은 id = 1234 뒤에, name = something 뒤에 나타납니다. int 비교가 발생할 수있는 문자열 비교는 비효율적입니다.
DataContext에서 다음 행을 사용하여 DataContext의 SQL 활동을 콘솔에 로그하십시오. 그러면 linq 문이 데이터베이스에서 요청한 내용을 정확하게 볼 수 있습니다.
_db.Log = Console.Out
다음 LINQ 문 :
var movies = from row in _db.Movies
orderby row.CategoryID, row.Name
select row;
과
var movies = _db.Movies.OrderBy(m => m.CategoryID).ThenBy(m => m.Name);
다음 SQL을 생성하십시오.
SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].CategoryID, [t0].[Name]
반면 Linq에서 OrderBy를 반복하면 결과 SQL 출력이 반대로 나타납니다.
var movies = from row in _db.Movies
orderby row.CategoryID
orderby row.Name
select row;
과
var movies = _db.Movies.OrderBy(m => m.CategoryID).OrderBy(m => m.Name);
다음 SQL을 생성하십시오 (이름 및 CategoryId가 전환됨).
SELECT [t0].ID, [t0].[Name], [t0].CategoryID
FROM [dbo].[Movies] as [t0]
ORDER BY [t0].[Name], [t0].CategoryID
나는 확장 메소드 (아래)를 만들었으므로 IQueryable이 이미 주문되어 있는지 걱정할 필요가 없습니다. 여러 속성으로 주문하려면 다음과 같이하십시오.
// We do not have to care if the queryable is already sorted or not.
// The order of the Smart* calls defines the order priority
queryable.SmartOrderBy(i => i.Property1).SmartOrderByDescending(i => i.Property2);
이것은 정렬 할 속성 목록에서 순서를 동적으로 생성 할 때 특히 유용합니다.
public static class IQueryableExtension
{
public static bool IsOrdered<T>(this IQueryable<T> queryable) {
if(queryable == null) {
throw new ArgumentNullException("queryable");
}
return queryable.Expression.Type == typeof(IOrderedQueryable<T>);
}
public static IQueryable<T> SmartOrderBy<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
if(queryable.IsOrdered()) {
var orderedQuery = queryable as IOrderedQueryable<T>;
return orderedQuery.ThenBy(keySelector);
} else {
return queryable.OrderBy(keySelector);
}
}
public static IQueryable<T> SmartOrderByDescending<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
if(queryable.IsOrdered()) {
var orderedQuery = queryable as IOrderedQueryable<T>;
return orderedQuery.ThenByDescending(keySelector);
} else {
return queryable.OrderByDescending(keySelector);
}
}
}
nullable datetime
가장 쉬운 방법은 아니지만 LINQ를 사용하여이 작업을 수행하는 방법이 하나 이상 있습니다. 를 사용하는 OrberBy()
메소드를 사용 하여이를 수행 할 수 있습니다 IComparer
. 먼저 당신은을 구현해야 IComparer
에 대한 Movie
이 같은 클래스 :
public class MovieComparer : IComparer<Movie>
{
public int Compare(Movie x, Movie y)
{
if (x.CategoryId == y.CategoryId)
{
return x.Name.CompareTo(y.Name);
}
else
{
return x.CategoryId.CompareTo(y.CategoryId);
}
}
}
그런 다음 다음 구문으로 영화를 주문할 수 있습니다.
var movies = _db.Movies.OrderBy(item => item, new MovieComparer());
항목 중 하나에 대해 순서를 내림차순으로 전환 해야하는 경우 그에 따라 Compare()
방법 내에서 x와 y를 전환하십시오 MovieComparer
.
MovieComparer
직접 만들 필요는 없습니다 . 대신에 할 수 있습니다 _db.Movies.OrderBy(item => item, Comparer<Movie>.Create((x, y) => { if (x.CategoryId == y.CategoryId) { return x.Name.CompareTo(y.Name); } else { return x.CategoryId.CompareTo(y.CategoryId); } }));
. 물론 if
... 대신에 하나의 표현식으로 논리를 작성하려는 경우 else
라마 (x, y) => expr
가 더 간단해질 수 있습니다.
일반 리포지토리를 사용하는 경우
> lstModule = _ModuleRepository.GetAll().OrderBy(x => new { x.Level,
> x.Rank}).ToList();
그밖에
> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();