2012-01-10 30 views
8

Đầu tiên Im a noob trong LINQ! Sau đó, điều là tôi có một Bộ sưu tập rằng:Trộn Bất kỳ() và Đầu tiên() trong LINQ?

  1. hoặc không chứa ID của tôi (string)
  2. hoặc chứa nó chỉ một lần

Tôi muốn sử dụng ở đâu nhưng tôi don 't thích if hướng dẫn mà tôi phải làm ... vì vậy đây là mã của tôi:

if (MyCollection.Any(rm => rm.BaseName == rbName)) 
{ 
    var tmp = MyCollection.First(rm => rm.BaseName == rbName); 
} 

này hoạt động nhưng tôi thực sự cảm thấy như thế này không phải là cách tôi nên làm điều đó với LINQ ... Bất kỳ đề xuất nào?

+0

bạn nên kiểm tra 'FirstOrDefault' – V4Vendetta

+0

Tại sao bạn không sử dụng FirstOrDefault(), và sau khi truy vấn bạn kiểm tra xem kết quả của bạn là null hay nó chứa dữ liệu của bạn? – BigL

+0

didnt biết phương pháp này: (Tôi thích SingleOrDefault anyway –

Trả lời

16

Non-Unique Entity trả lời (với ngoại lệ ném vào nhiều trường hợp)

Sử dụng SingleOrDefault. Điều này sẽ trả về mục duy nhất nếu nó tồn tại, null nếu nó không tồn tại hoặc nó sẽ ném và ngoại lệ nếu có nhiều hơn một.

var tmp = MyCollection.SingleOrDefault(rm => rm.BaseName == rbName); 

Unique tài sản trả lời (sẽ không bao giờ có nhiều trường hợp)

Nếu hệ thống của bạn được thiết lập để BaseName là một thực thể độc đáo, sử dụng FirstOrDefault, điều này sẽ không ném một ngoại lệ nếu có nhiều như nó sẽ dừng lại ở ví dụ đầu tiên, nhưng hệ thống sẽ được thiết kế sao cho sẽ không bao giờ có cùng một thể hiện, vì vậy nó sẽ được chấp nhận (và giảm thời gian).

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName); 
+0

Điều này thực sự tốt đẹp! Xử lý ngoại lệ là rất tốt đẹp :) –

+1

Nó là tốt đẹp trong một cách mà nếu có bao giờ một trận đấu sau đó nó sẽ ném một ngoại lệ, nhưng nếu hệ thống của bạn được thiết lập rằng nó không thể cho một bản sao sau đó ngoại lệ sẽ không bao giờ được yêu cầu sau đó đi với FirstOrDefault (chỉ khi đó là một khóa chính hoặc đã thiết lập xác nhận khi chèn). – ThePower

5
var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName)); 

Đây tmp sẽ được null nếu bạn không có kỷ lục như vậy.

1

Any lợi nhuận bool để chỉ ra nếu mặt hàng như vậy tồn tại, First trả về các bản ghi từ bộ sưu tập của bạn. Vì vậy, trong mọi trường hợp, bạn sẽ có đối tượng từ bộ sưu tập và kết quả điều kiện của bạn. Bạn có thể sử dụng FirstOrDefault và sau đó kiểm tra null giá trị trả lại của bạn.

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName); 
if (tmp != null) 
{ 
    // do something 
} 
2

bạn có thể sử dụng,

FirstOrDefault() 

hoặc

SingleOrDefault() 
1
var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName); 
if (tmp != null) 
{ 
    // Do something 
} 
12

Như ThePower nói, bạn nên sử dụng SingleOrDefault hoặc có lẽ FirstOrDefault. Nếu thực sự chỉ có một mục nhập như vậy, chúng sẽ thực hiện tương tự, nhưng FirstOrDefault cũng có thể nhanh hơn nếu bạn đang sử dụng LINQ to Objects - SingleOrDefault sẽ phải quét qua chuỗi hoàn chỉnh để kiểm tra xem không có bất kỳ kết quả trùng khớp nào khác .

Nếu có nhiều kết quả phù hợp, SingleOrDefault sẽ ném một ngoại lệ; FirstOrDefault sẽ chỉ trả về trận đấu đầu tiên.

Vì vậy, bạn có thể sử dụng:

var result = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName); 
if (result != null) 
{ 
    // Use it 
} 

Lưu ý rằng điều này có thể vụng về nếu loại yếu tố chuỗi của bạn là một loại giá trị, như bạn có thể không có khả năng phân biệt giữa các giá trị mặc định cho các loại nguyên tố do không có kết quả phù hợp và giá trị "thực". Có vẻ như đó không phải là vấn đề trong trường hợp này, nhưng nó đáng ghi nhớ.

+0

cảm ơn vì các biện pháp này! :) –

+0

Điểm tốt Jon. Đó là khó khăn để xem cho dù đó là một khóa chính hoặc yếu tố duy nhất được xác định, một sự bổ sung tuyệt vời tuy nhiên. – ThePower

Các vấn đề liên quan