Câu trả lời ngắn: LINQ to Objects sử dụng thuật toán sắp xếp ổn định, và LINQ to SQL phụ thuộc vào việc triển khai cơ sở dữ liệu theo thứ tự thường không xác định.
Thuật toán sắp xếp xác định là thuật toán luôn có cùng hành vi trên các lần chạy khác nhau.
Trong ví dụ này, bạn có các bản sao trong mệnh đề OrderBy của mình. Đối với loại được bảo đảm và được dự đoán, một trong các mệnh đề đơn đặt hàng hoặc kết hợp mệnh đề đơn đặt hàng phải là duy nhất.
Trong LINQ, bạn có thể đạt được điều này bằng cách thêm mệnh đề OrderBy khác để tham chiếu thuộc tính duy nhất của bạn, như trong
items.OrderBy(i => i.Rate).ThenBy(i => i.ID)
.
Long trả lời:
LINQ to Objects sử dụng một loại ổn định, như tài liệu trong liên kết này: MSDN.
Trong LINQ to SQL, nó phụ thuộc vào thuật toán sắp xếp của cơ sở dữ liệu bên dưới và thường là một kiểu không ổn định, như trong MS SQL Server (MSDN).
Trong một loại ổn định, nếu các phím của hai phần tử bằng nhau, thứ tự của các phần tử được giữ nguyên.Ngược lại, một loại không ổn định không bảo toàn thứ tự các phần tử có cùng khóa.
Vì vậy, đối với LINQ to SQL, việc phân loại thường không xác định vì RDMS (Relational Hệ thống quản lý cơ sở dữ liệu, như MS SQL Server) có thể trực tiếp sử dụng một thuật toán sắp xếp ổn định với một lựa chọn trục ngẫu nhiên hoặc sự ngẫu nhiên có thể liên quan đến hàng nào mà cơ sở dữ liệu xảy ra để truy cập đầu tiên trong hệ thống tệp.
Ví dụ: hãy tưởng tượng rằng kích thước của một trang trong hệ thống tệp có thể chứa tối đa 4 hàng.
Trang sẽ được đầy đủ nếu bạn chèn các dữ liệu sau:
Page 1
| Name | Value |
|------|-------|
| A | 1 |
| B | 2 |
| C | 3 |
| D | 4 |
Nếu bạn cần phải chèn một hàng mới, các RDMS có hai lựa chọn:
- Tạo một trang mới để phân bổ hàng mới.
- Chia trang hiện tại thành hai trang. Vì vậy, trang đầu tiên sẽ giữ các Tên A và B và trang thứ hai sẽ giữ C và D.
Giả sử RDMS chọn tùy chọn 1 (để giảm phân đoạn chỉ mục). Nếu bạn chèn một dòng mới với Tên C và giá trị , bạn sẽ nhận được:
Page 1 Page 2
| Name | Value | | Name | Value |
|------|-------| |------|-------|
| A | 1 | | C | 9 |
| B | 2 | | | |
| C | 3 | | | |
| D | 4 | | | |
lẽ, mệnh đề OrderBy trong cột Tên sẽ trở lại như sau:
| Name | Value |
|------|-------|
| A | 1 |
| B | 2 |
| C | 3 |
| C | 9 | -- Value 9 appears after because it was at another page
| D | 4 |
Bây giờ, giả sử rằng RDMS chọn tùy chọn 2 (để tăng hiệu suất chèn trong hệ thống lưu trữ có nhiều cọc). Nếu bạn chèn một dòng mới với Tên C và giá trị , bạn sẽ nhận được:
Page 1 Page 2
| Name | Value | | Name | Value |
|------|-------| |------|-------|
| A | 1 | | C | 3 |
| B | 2 | | D | 4 |
| C | 9 | | | |
| | | | | |
lẽ, mệnh đề OrderBy trong cột Tên sẽ trở lại như sau:
| Name | Value |
|------|-------|
| A | 1 |
| B | 2 |
| C | 9 | -- Value 9 appears before because it was at the first page
| C | 3 |
| D | 4 |
Về ví dụ của bạn:
Tôi tin rằng bạn đã nhập sai điều gì đó trong câu hỏi của mình, bởi vì bạn đã sử dụng items.OrderBy(i => i.rate).Skip(2).Take(2);
và kết quả đầu tiên không hiển thị một hàng với Rate = 2
.Điều này là không thể vì Skip
sẽ bỏ qua hai hàng đầu tiên và chúng có Rate = 1
, vì vậy, đầu ra của bạn phải hiển thị hàng với Rate = 2
.
Bạn đã gắn thẻ câu hỏi của mình với database
, vì vậy tôi tin rằng bạn đang sử dụng LINQ to SQL. Trong trường hợp này, kết quả có thể không xác định và bạn có thể nhận được như sau:
Kết quả 1:
[{"id":40, "description":"aaa", "rate":1},
{"id":4, "description":"ccc", "rate":2}]
Kết quả 2:
[{"id":1, "description":"bbb", "rate":1},
{"id":4, "description":"ccc", "rate":2}]
Nếu bạn đã sử dụng items.OrderBy(i => i.rate).ThenBy(i => i.ID).Skip(2).Take(2);
thì kết quả chỉ có thể sẽ là:
[{"id":40, "description":"aaa", "rate":1},
{"id":4, "description":"ccc", "rate":2}]
Nếu bạn không chỉ định thứ tự thì không có bảo đảm. Nếu bạn chỉ định một số cột, ví dụ: 'thứ tự theo tỷ lệ, mô tả', sau đó nó sẽ sắp xếp theo' tốc độ' và sau đó, trong đó 'giá trị' giá trị lặp lại,' mô tả'. Vẫn có thể có nhiều hàng có giá trị bằng nhau cho cả 'tốc độ' và' mô tả' và thứ tự của chúng sẽ không được chỉ định. 'id' thường được sử dụng như một bộ ngắt kết nối để đảm bảo thứ tự ổn định:' thứ tự theo tỷ lệ, mô tả, id'. – HABO
Lý do thực tế cho việc tại sao thứ tự có thể khác: Một số thuật toán sắp xếp nhanh sẽ chọn ngẫu nhiên lựa chọn trục. – usr