2011-10-19 22 views

Trả lời

18

Find kiểm tra trước tiên nếu thực thể có khóa đã cho đã có trong ngữ cảnh. Nếu không, nó sẽ truy vấn cơ sở dữ liệu. Có thể nó sử dụng trong trường hợp này là truy vấn LINQ sử dụng SingleOrDefault. SingleOrDefault chuyển thành SELECT TOP 2 để có thể ném ngoại lệ nếu kết quả có nhiều hơn một thực thể.

Vì vậy, tại sao không Find sử dụng FirstOrDefault (có thể dịch thành SELECT TOP 1). Tôi không biết, nhưng tôi đoán rằng Find muốn kiểm tra xem thực thể có thực sự duy nhất trong cơ sở dữ liệu hay không. Nó nên - vì đó là khóa chính mà truy vấn sử dụng - nhưng mô hình và cơ sở dữ liệu có thể không đồng bộ vì ai đó đã thay đổi khóa chính trong cơ sở dữ liệu, ví dụ: thêm cột vào khóa tổng hợp trong cơ sở dữ liệu nhưng không có trong mô hình.

Thực sự chỉ là giả thuyết. Chỉ có nhóm phát triển EF mới có thể trả lời chính xác lý do.

Sửa

Nếu tôi làm điều này như mô tả ở trên (thêm cột để chìa khóa composite trong DB và thêm bản ghi có cùng giá trị trong cột then chốt đầu tiên) và gọi đó Find, tôi nhận được ngoại lệ. ..

chuỗi chứa nhiều hơn một yếu tố

... và stacktrace này:

01.
//... 
System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source) 
System.Data.Entity.Internal.Linq.InternalSet`1.FindInStore(
    WrappedEntityKey key, String keyValuesParamName) 
System.Data.Entity.Internal.Linq.InternalSet`1.Find(Object[] keyValues) 
System.Data.Entity.DbSet`1.Find(Object[] keyValues) 

Vì vậy, có vẻ như Find thực sự sử dụng SingleOrDefault.

+0

Khi tôi chạy SingleOrDefault thông qua LinqPad và VS Tôi không bao giờ chọn SELECT TOP 2. Bạn nhận được từ đâu? Điều đó có phù hợp với EF không? –

+0

@JamieRRytlewski: Đó là trường hợp của EF, vâng. Tôi không chắc là nó có độc quyền với EF không. Bạn đã kiểm tra cái gì? Với LINQ to SQL? – Slauma

+0

Vâng tôi đã sử dụng LINQ to Sql .... vì vậy nó phải là một sự khác biệt. Tôi đã làm một số đọc và nó xuất hiện như thể nó chỉ hiển thị với EF. Nó có ý nghĩa để có TOP2, tôi chưa bao giờ thấy nó vì tôi không sử dụng EF. –

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