Điều này sẽ hiệu quả với bạn:
Điều này sẽ phù hợp với bạn:
var movies = _db.Movies.OrderBy(c => c.Category).ThenBy(n => n.Name)
Sử dụng cú pháp truy vấn LINQ không phải lambda, bạn có thể thực hiện điều này:
Sử dụng cú pháp truy vấn LINQ không phải lambda, bạn có thể thực hiện các thao tác sau:
var movies = từ hàng trong _db.Movies
sắp xếp theo hàng.Thể loại, hàng.Tên
chọn hàng;
[CHỈNH SỬA để giải quyết bình luận] Để kiểm soát thứ tự sắp xếp, hãy sử dụng các từ khóa đang tăng dần
(là mặc định và do đó không thực sự hữu ích) hoặc đang đi xuống
, như thế này:
[CHỈNH SỬA ĐỊA CHỈ BÌNH LUẬN] Để kiểm soát thứ tự sắp xếp, hãy sử dụng từ khóa tăng dần (mặc định, do đó không đặc biệt hữu ích) hoặc giảm dần, như hiển thị bên dưới:
var movies = từ hàng trong _db.Movies
sắp xếp theo hàng. Thể loại giảm dần, hàng. Tên
chọn hàng;
Thêm "mới":
Thêm "mới":
var movies = _db.Movies.OrderBy( m => new { m.CategoryID, m.Name })
Điều đó có tác dụng với hộp của tôi. Nó trả về thứ gì đó có thể được sử dụng để sắp xếp. Nó trả về một đối tượng có hai giá trị.
Điều này hoạt động tốt cho hộp của tôi. Nó trả về một cái gì đó có thể được sử dụng để sắp xếp. Nó trả về một đối tượng có hai giá trị.
Tương tự nhưng khác với việc sắp xếp theo cột kết hợp như sau.
Tương tự như sắp xếp theo cột kết hợp, nhưng khác như minh họa bên dưới.
var movies = _db.Movies.OrderBy( m => (m.CategoryID.ToString() + m.Name))
Sử dụng dòng sau trên Dữ liệuBối cảnh
để ghi lại hoạt động SQL trên Dữ liệuBối cảnh
vào bảng điều khiển - sau đó bạn có thể thấy chính xác những câu lệnh LINQ của bạn đang yêu cầu gì từ cơ sở dữ liệu:
Sử dụng dòng sau trên DataContext để ghi nhật ký hoạt động SQL trên DataContext vào bảng điều khiển - khi đó bạn có thể xem chính xác câu lệnh LINQ của mình đang yêu cầu gì từ cơ sở dữ liệu:
_db.Log = Console.Out
Các câu lệnh LINQ sau đây:
Câu lệnh LINQ sau:
var movies = từ hàng trong _db.Movies
sắp xếp theo hàng.CategoryID, hàng.Name
chọn hàng;
VÀ
Và
var movies = _db.Movies.OrderBy(m => m.CategoryID).ThenBy(m => m.Name);
tạo ra câu SQL sau:
SQL sau được tạo:
CHỌN [t0].ID, [t0].[Tên], [t0].CategoryID
TỪ [dbo].[Phim] như [t0]
SẮP XẾP THEO [t0].CategoryID, [t0].[Tên]
Trong khi đó, lặp lại một Đặt hàngBy
trong LINQ, dường như đảo ngược kết quả đầu ra SQL:
Tuy nhiên, việc lặp lại OrderBy trong LINQ dường như đảo ngược kết quả đầu ra SQL:
var movies = từ hàng trong _db.Movies
sắp xếp theo hàng.CategoryID
đặt hàng theo hàng.Name
chọn hàng;
VÀ
Và
var movies = _db.Movies.OrderBy(m => m.CategoryID).OrderBy(m => m.Name);
tạo ra SQL sau (Name và CategoryId được hoán đổi):
Tạo SQL sau (tên và ID danh mục được hoán đổi):
CHỌN [t0].ID, [t0].[Tên], [t0].CategoryID
TỪ [dbo].[Phim] như [t0]
SẮP XẾP THEO [t0].[Tên], [t0].CategoryID
Tôi đã tạo một số phương thức mở rộng (bên dưới) để bạn không phải lo lắng liệu IQueryable đã được sắp xếp hay chưa. Nếu bạn muốn sắp xếp theo nhiều thuộc tính, chỉ cần thực hiện như sau:
Tôi đã tạo một số phương thức mở rộng (bên dưới) để bạn không phải lo lắng về việc liệu IQueryable đã được sắp xếp chưa. Nếu bạn muốn sắp xếp theo nhiều thuộc tính, hãy làm điều này:
// Chúng ta không cần quan tâm đến việc dữ liệu truy vấn đã được sắp xếp hay chưa.
// Thứ tự của các lệnh gọi Smart* xác định thứ tự ưu tiên
có thể truy vấn.SmartOrderBy(i => i.Property1).SmartOrderByDescending(i => i.Property2);
Điều này đặc biệt hữu ích nếu bạn tạo thứ tự động từ danh sách các thuộc tính để sắp xếp.
Điều này đặc biệt hữu ích nếu bạn tạo sắp xếp động, chọn từ danh sách thuộc tính để sắp xếp.
lớp tĩnh công khai IQueryableExtension
{
public static bool IsOrdered(this IQueryable có thể truy vấn) {
nếu(có thể truy vấn == null) {
ném ArgumentNullException mới ("có thể truy vấn");
}
trả về queryable.Expression.Type == typeof(IOrderedQueryable);
}
public static IQueryable SmartOrderBy(điều này IQueryable có thể truy vấn, Expression<>> keySelector) {
nếu(có thể truy vấn.IsOrdered()) {
var orderedQuery = có thể truy vấn như IOrderedQueryable;
trả về orderedQuery.ThenBy(keySelector);
} khác {
trả về queryable.OrderBy(keySelector);
}
}
public static IQueryable SmartOrderByDescending(this IQueryable có thể truy vấn, Expression<>> keySelector) {
nếu(có thể truy vấn.IsOrdered()) {
var orderedQuery = có thể truy vấn như IOrderedQueryable;
trả về orderedQuery.ThenByDescending(keySelector);
} khác {
trả về queryable.OrderByDescending(keySelector);
}
}
}
Có ít nhất một cách nữa để thực hiện việc này bằng cách sử dụng LINQ, mặc dù không phải là cách dễ nhất.
Bạn có thể làm điều đó bằng cách sử dụng OrberBy()
phương pháp sử dụng một IComparer
. Đầu tiên bạn cần phải
thực hiện một IComparer
cho Bộ phim
lớp như thế này:
Có ít nhất một cách để thực hiện việc này bằng LINQ, mặc dù đây không phải là cách đơn giản nhất. Bạn có thể thực hiện việc này bằng phương thức OrberBy() sử dụng IComparer. Trước tiên, bạn cần triển khai IComparer cho lớp Movie, như hiển thị bên dưới:
lớp công khai MovieComparer : IComparer
{
public int So sánh(Phim x, Phim y)
{
nếu (x.CategoryId == y.CategoryId)
{
trả về x.Name.CompareTo(y.Name);
}
khác
{
trả về x.CategoryId.CompareTo(y.CategoryId);
}
}
}
Sau đó, bạn có thể đặt hàng phim theo cú pháp sau:
Sau đó, bạn có thể sắp xếp phim bằng cú pháp sau:
var movies = _db.Movies.OrderBy(item => item, new MovieComparer());
Nếu bạn cần chuyển đổi thứ tự giảm dần cho một trong các mục, chỉ cần chuyển đổi x và y bên trong So sánh()
phương pháp của So sánh phim
theo đó.
Nếu bạn cần chuyển cách sắp xếp của một trong các mục sang thứ tự giảm dần, chỉ cần chuyển x và y tương ứng trong phương thức Compare() của MovieCompeller.
Nếu sử dụng kho lưu trữ chung
Nếu sử dụng kho lưu trữ chung
> lstModule = _ModuleRepository.GetAll().OrderBy(x => new { x.Level,
> x.Xếp hạng}).ToList();
khác
khác
> _db.Module.Where(x=> ......).OrderBy(x => new { x.Level, x.Rank}).ToList();
Thêm câu trả lời
Cảm ơn câu trả lời của bạn tất nhiên... Nhưng thay vì Var movies = _db.Movies.Orderby(c => c.Category).ThenBy(n => n.Name)
nếu tôi sử dụng Var movies = _db.Movies.Orderby(c => c.Category).OrderBy(n => n.Name)
Tại sao gõ "orderBy" 2 lần lại cho kết quả khác nhau?
Tất nhiên, cảm ơn câu trả lời của bạn... thay vì Var Movies.Orderby(c=>c.Category).ThenBy(n=>n.Name) nếu tôi sử dụng Var Movies.Orderby(c=>c.Category) .OrderBy( n=>n.Name) "orderBy" hai lần, tại sao kết quả lại khác nhau?
@devendra, kết quả khác nhau vì "OrderBy" thứ hai hoạt động trên bộ sưu tập là kết quả của "OrderBy" đầu tiên và sắp xếp lại các mục của nó
@Devendra, kết quả khác vì "OrderBy" thứ hai xử lý bộ sưu tập là kết quả của "OrderBy" đầu tiên và sắp xếp lại các mục của nó
ThenBy hoạt động trên IOrderedEnumerable (được trả về bởi OrderBy)
ThenBy hoạt động trên IOrderedEnumerable (được trả về bởi OrderBy)
Xin lưu ý: .ThenBy()
= Tăng dần và .ThenByDescending()
= Giảm dần!! (nghe có vẻ hợp lý phải không?)
Xin lưu ý: .ThenBy() = thứ tự tăng dần, .ThenByDescending() = thứ tự giảm dần! ! (Nghe có vẻ hợp lý phải không?)
IQueryable không chứa định nghĩa cho ThenBycó thể truy vấn đượcKhông chứa định nghĩa của ThenBy
Không có cách nào để chuyển đổi qua lại giữa descending và non trong cú pháp này phải không?
Không có cách nào chuyển đổi qua lại giữa giảm dần và không theo cú pháp này phải không?
Thực ra, câu trả lời của bạn tương đương với _db.Movies.Orderby(c => c.Thể loại).OrderBy(n => n.Tên)
. Đúng hơn là từ hàng trong _db.Movies sắp xếp theo hàng. Thể loại theo thứ tự giảm dần theo hàng. Tên chọn hàng
Trên thực tế, câu trả lời của bạn tương đương với _db.Movies.Orderby(c=>c.Category).OrderBy(n=>n.Name). Đúng hơn là từ hàng in_db. Phim theo thứ tự dòng. Danh mục giảm dần theo thứ tự hàng. Dòng chọn tên
@Lodewijk: Tôi tin là bạn đã hiểu ngược lại. Ví dụ của bạn sẽ kết thúc bằng việc row.Name là cột chính và row.Category là cột phụ, tương đương với _db.Movies.Orderby(c => c.Thể loại).OrderBy(n => n.Tên)
. Hai đoạn trích bạn cung cấp tương đương với nhau, không tương đương với OP.
@Lodewijk: Tôi tin rằng bạn đã hoàn toàn đảo ngược điều này. Ví dụ của bạn sẽ có row.Name là cột chính và row.Category là cột phụ, tương đương với _db.Movies.Orderby(c=>c.Category).OrderBy(n=>n.Name). Hai đoạn mã bạn cung cấp tương đương với nhau chứ không tương đương với OP.
Nhược điểm duy nhất khi sử dụng cú pháp SQL cho Linq là không phải tất cả các hàm đều được hỗ trợ, hầu hết nhưng không phải tất cả
Nhược điểm duy nhất khi sử dụng cú pháp SQL với Linq là không phải tất cả các hàm đều được hỗ trợ, hầu hết nhưng không phải tất cả các hàm đều được hỗ trợ
Hãy cẩn thận khi sử dụng nó cho các con số.
Hãy cẩn thận khi sử dụng điều này với các con số.
Bạn có thể sử dụng OrderByDescending và ThenBy, hoặc OrderBy và ThenByDescending, tùy theo nhu cầu của bạn.
Bạn có thể sử dụng OrderByDescending và ThenBy hoặc OrderBy và ThenByDescending, tùy theo nhu cầu của bạn.
Tôi khá chắc chắn rằng .OrderBy( m => new { m.CategoryID, m.Name })
Và .OrderBy( m => new { m.Name, m.CategoryID })
sẽ tạo ra cùng một kết quả thay vì tôn trọng mức độ ưu tiên dự định. Đôi khi nó sẽ xuất hiện để cung cấp cho bạn thứ tự bạn muốn hoàn toàn ngẫu nhiên. Ngoài ra m.CategoryID.ToString() + m.Name
sẽ tạo ra các lệnh không chính xác nếu CategoryID là số nguyên
. Ví dụ, thứ gì đó có id=123, name=5times sẽ xuất hiện sau id=1234, name=something thay vì trước đó. Cũng không kém hiệu quả khi thực hiện so sánh chuỗi trong khi có thể xảy ra so sánh int.
Tôi khá chắc chắn rằng .OrderBy(m=>new{m.CategoryID, m.Name}) và .OrderBy(m=>new{m.Name, m.CategoryID}) sẽ tạo ra kết quả tương tự thay vì tôn trọng lớp ưu tiên dự kiến. Đôi khi nó dường như mang lại cho bạn thứ tự bạn muốn chỉ bằng sự trùng hợp ngẫu nhiên. Ngoài ra, m.CategoryID.ToString()+m.Name sẽ tạo ra sự sắp xếp không chính xác nếu CategoryID là số nguyên. Ví dụ: nội dung có id=123, name=5 lần sẽ xuất hiện sau id=1234, name=Something, không phải trước đó. Việc so sánh chuỗi trong đó có thể xảy ra so sánh int cũng không hiệu quả.
Khi tôi thử sắp xếp theo kiểu ẩn danh, tôi nhận được ArgumentException với thông báo "Ít nhất một đối tượng phải triển khai IComparable". Tôi thấy những người khác phải khai báo trình so sánh khi thực hiện việc này. Xem stackoverflow.com/questions/10356864/… .
Khi tôi cố gắng sắp xếp một loại ẩn danh, tôi nhận được một ngoại lệ ArgumentException với thông báo "Ít nhất một đối tượng phải triển khai ICompable." Tôi đã thấy những đối tượng khác làm điều này khi họ phải khai báo một bộ so sánh. Xem Stackoverflow.com/Questions/10356864/….
Điều này hoàn toàn sai. Sắp xếp theo kiểu ẩn danh mới không có triển khai ICompariable không thể hoạt động, vì không có thứ tự cho các thuộc tính của kiểu ẩn danh. Nó sẽ không biết sắp xếp theo CategoryID trước hay Name trước, chưa nói đến việc sắp xếp theo thứ tự ngược nhau.
Điều này hoàn toàn sai. Sắp xếp theo loại ẩn danh mới mà không triển khai ICompiable không hoạt động vì thuộc tính của loại ẩn danh không được sắp xếp. Nó không biết nên sắp xếp theo CategoryID hay Name trước chứ chưa nói đến thứ tự ngược lại.
Câu trả lời này thật tuyệt vời! Tôi sẽ kết hợp kiểm tra queryable.IsOrdered() với câu trả lời từ bài đăng này để có một phương thức duy nhất có hướng sắp xếp: stackoverflow.com/questions/388708
Câu trả lời này là vàng! Tôi sẽ kết hợp việc kiểm tra queryable.IsOrded() với câu trả lời từ bài viết này để có cách thực hiện hướng sắp xếp: Stackoverflow.com/Questions/388708
Theo cách này, việc triển khai Linq nên được thực hiện ngay từ đầu! OrderBy được thiết kế tệ...
Vì vậy, việc triển khai Linq phải được ưu tiên hàng đầu! OrderBy được thiết kế kém...
Bạn có thể dễ dàng mở rộng phần mở rộng này để xem xét các giá trị có thể chấp nhận giá trị null. Tham khảo: stackoverflow.com/a/36507021
Bạn có thể dễ dàng mở rộng tiện ích mở rộng này để tính các giá trị rỗng. Xem: Stackoverflow.com/a/36507021
Tôi thích điều này vì nó tổng quát hơn thenby vì bạn có thể làm những điều kỳ lạ với compare bao gồm việc có các đối tượng compare khác nhau với các thuật toán khác nhau sẵn sàng để sử dụng. Điều này tốt hơn giải pháp ưa thích của tôi trước khi tìm hiểu về thenby là tạo một lớp triển khai giao diện IComparable.
Tôi thích làm điều này vì nó tổng quát hơn so với trước đây, bởi vì bạn có thể làm những điều kỳ lạ bằng cách so sánh, bao gồm cả việc chuẩn bị sẵn các đối tượng so sánh khác nhau và các thuật toán khác nhau. Giải pháp này tốt hơn giải pháp ưa thích của tôi trước khi tìm hiểu về vấn đề này, đó là tạo một lớp triển khai giao diện ICompable.
Kể từ năm 2012 (.NET phiên bản 4.5), bạn không cần phải tạo lớp So sánh phim
chính bạn; thay vào đó bạn có thể làm _db.Movies.OrderBy(item => item, Comparer.Create((x, y) => { nếu (x.CategoryId == y.CategoryId) { trả về x.Name.CompareTo(y.Name); } nếu không { trả về x.CategoryId.CompareTo(y.CategoryId); } }));
. Tất nhiên, nếu bạn thích viết logic dưới dạng một biểu thức, thay vì nếu như
...khác
, sau đó là lamda (x, y) => biểu thức
có thể đơn giản hơn.
Bắt đầu từ năm 2012 (.NET phiên bản 4.5), bạn không cần phải tự tạo lớp MovieCompeller; thay vào đó, bạn có thể thực hiện _db.Movies.OrderBy(Item => Item, Compeller)..Create((x,y)=>{if(x.CategoryId==y.CategoryId){Return x.Name.CompareTo(y.Name);}Else{Return x.CategoryId.CompareTo(y.CategoryId); }}));. Tất nhiên, nếu bạn thích viết logic của mình dưới dạng biểu thức hơn là if...Else, thì lamda(x,y)=>expr có thể đơn giản hơn.
Biểu thức ẩn danh sẽ được phân tích cục bộ bởi lõi khung thực thể. Biểu thức LINQ không thể được dịch và sẽ được đánh giá cục bộ.
Các biểu thức ẩn danh sẽ được Entity Framework Core phân tích cú pháp nguyên bản. Không thể chuyển đổi biểu thức LINQ, nó sẽ được đánh giá cục bộ.
Tôi là một lập trình viên xuất sắc, rất giỏi!