Tôi nghĩ rằng thứ tự của các yếu tố lấy ra bằng một LINQ
được bảo tồn, ít nhất là cho LINQ to Object
, cho LINQ to SQL or Entity
, nó có thể phụ thuộc vào thứ tự của các bản ghi trong bảng. Đối với LINQ to Object
, tôi sẽ cố gắng giải thích lý do tại sao nó giữ nguyên thứ tự.
Trong thực tế khi truy vấn LINQ
được thực thi, nguồn IEnumerable
sẽ gọi điện để GetEnumerator()
để bắt đầu vòng lặp với một while loop
và nhận được phần tử tiếp theo sử dụng MoveNext()
. Đây là cách foreach
hoạt động trên nguồn IEnumerable
. Chúng ta đều biết rằng foreach
sẽ giữ nguyên thứ tự của các thành phần trong danh sách/bộ sưu tập. Đào sâu hơn vào MoveNext()
, tôi nghĩ nó chỉ có một số Position
để lưu Index
và MoveNext()
hiện tại chỉ tăng Position
và yield
thành phần tương ứng (ở vị trí mới). Đó là lý do tại sao cần giữ nguyên thứ tự, tất cả các mã thay đổi thứ tự ban đầu là dư thừa hoặc bằng cách gọi một cách rõ ràng đến OrderBy
hoặc OrderByDescending
.
Nếu bạn nghĩ rằng đây
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
foreach(var i in numbers)
if(i < 5) Console.Write(i + " ");
in ra 4 1 3 2 0
bạn nên nghĩ rằng đây
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
IEnumerator ie = numbers.GetEnumerator();
while(ie.MoveNext()){
if((int)ie.Current < 5) Console.Write(ie.Current + " ");
}
cũng in ra 4 1 3 2 0
. Do đó, truy vấn LINQ
var lowNums = from n in numbers
where n < 5
select n;
foreach (var i in lowNums) {
Console.Write(i + " ");
}
cũng sẽ in ra 4 1 3 2 0
.
Kết luận: Trình tự của các yếu tố trong LINQ
phụ thuộc vào cách MoveNext()
của một IEnumerator
thu được từ một IEnumerable
được thực hiện. Tuy nhiên, chắc chắn rằng thứ tự các phần tử trong kết quả LINQ
sẽ giống với một vòng lặp foreach
hoạt động trên các phần tử.
Sử dụng 'var lowNums = numbers.Where (x => x <5).OrderBy (x => x); ' –
Có thể điều này sẽ giúp: http://stackoverflow.com/questions/6146724/do-linqs-enumerable-methods-maintain-relative-order-of-elements. Nếu đó là một IEnumerable, nó sẽ mantain thứ tự ban đầu. – thepirat000