2011-08-16 27 views
8

Xin chào, tôi đang cố gắng sử dụng chức năng DefaultIfEmpty() trên IQueryable và nó ném ngoại lệ "Quá tải không được hỗ trợ được sử dụng cho toán tử truy vấn 'DefaultIfEmpty'." đây là mã của tôi:DefaultIfEmpty() không hoạt động

Dinner defaultDinner = db.Dinners.Where(d => d.DinnerID == 5).Single(); 
Dinner blah; 
IQueryable<Dinner> bla = db.Dinners.Where(d => d.DinnerID == id) 
          .DefaultIfEmpty(defaultDinner); 
blah = bla.First(); 
return blah; 

Tôi tìm thấy một cách khác để làm điều đó mà không DefaultIfEmpty nhưng tôi vẫn muốn biết làm thế nào để giải quyết này ... đây là phần đầu tiên của ngoại lệ:

Mô tả: Một ngoại lệ không được xử lý xảy ra trong khi thực hiện yêu cầu web hiện tại. Vui lòng xem lại dấu vết ngăn xếp để biết thêm thông tin về lỗi và vị trí bắt nguồn từ mã.

Chi tiết ngoại lệ: System.NotSupportedException: Quá tải không được hỗ trợ được sử dụng cho toán tử truy vấn 'DefaultIfEmpty'.

Trả lời

14

Nó có vẻ khá tự giải thích với tôi:

quá tải không được hỗ trợ sử dụng cho các nhà khai thác truy vấn 'DefaultIfEmpty'

Âm thanh như nhà cung cấp LINQ của bạn (mà bạn chưa chỉ định) không hỗ trợ quá tải DefaultIfEmpty giá trị siêu.

Giải pháp thay thế đơn giản nhất có lẽ là để sử dụng:

var ret = db.Dinners.Where(d => d.DinnerID == id) 
        .FirstOrDefault(); 
return ret ?? db.Dinners.Where(d => d.DinnerID == 5).Single(); 

Lưu ý rằng phương pháp này tránh được lấy là "mặc định" ăn tối trừ khi nó được yêu cầu, do đó, nó hiệu quả hơn nữa.

(Nếu chỉ có phải là một kết quả duy nhất đối với bất kỳ ID, có lẽ bạn nên sử dụng SingleOrDefault thay vì FirstOrDefault bằng cách này. Đó là hợp lý hơn theo cách đó.)

+0

Tôi đang sử dụng: system.data.linq.table –

+0

@Ella: Vì vậy, LINQ to SQL sau đó ... –

+0

Có, LINQ to sql db –

2

Thử

Dinner dinner = db.Dinners.SingleOrDefault(d => d.DinnerID == id); 
+0

Phương thức 'Mặc định' nào? Tôi không quen với nó trong Queryable ... –

+0

Vấn đề ở đây là '' Default'' được trả về bởi '' SingleOrDefault'' là giá trị mặc định * cho kiểu * đó. Trong trường hợp này, vì '' Dinner'' là một lớp, nó sẽ là '' null''. – BishopRook

+0

@Jon Skeet: loại bỏ điều này, tôi đã trộn nó với một cái gì đó không thể nhớ chính xác .. nhưng một nơi nào đó tôi thấy cú pháp như vậy – sll

1

Phương pháp DefaultIfEmpty ném một NotSupportedException khi kêu gọi một IQueryable<T>. Bạn có thể thực hiện một dàn diễn viên rõ ràng cho một số IEnumerable<T> bằng cách gọi db.Dinners.Where(d => d.DinnerId == id).ToEnumerable().First().

Bạn có thể không nên sử dụng phương pháp này mặc dù. Tốt hơn là chỉ cần kiểm tra xem cuộc gọi có trả về bất kỳ giá trị nào hay không và truy xuất giá trị mặc định nếu không.

Chỉnh sửa: Oop. Không, Jon Skeet là chính xác. Phương thức mở rộng DefaultIfEmpty dựa trên việc triển khai từ nhà cung cấp truy vấn, do đó, nó chắc chắn phụ thuộc vào nhà cung cấp truy vấn nào đang được sử dụng.

+0

Chắc chắn có hay không nó ném một ngoại lệ phụ thuộc vào * triển khai * của IQueryable . Không có gì ngăn nó xử lý toán tử đó mà không có vấn đề gì. –

+0

'' DefaultIfEmpty'' là một phương thức mở rộng trong '' System.Linq'', nó không phải là thành viên của lớp thực hiện '' IQueryable '' * hoặc * '' IEnumerable ''. Vì vậy, không, tôi không thấy cách thực hiện sẽ quan trọng? – BishopRook

+0

Đó là một phương thức mở rộng trong Queryable, yes - thực hiện các cuộc gọi trên 'IQueryable ' trong tham số đầu tiên. Việc triển khai thực hiện * rất * rất nhiều vấn đề. Ví dụ, hãy thử 'string y = new string [0] .AsQueryable(). DefaultIfEmpty (" foo "). Đầu tiên();' - thành công sẽ không thành vấn đề, mặc dù vẫn gọi 'Queryable.DefaultIfEmpty'. –