2010-03-16 30 views
5

Lưu ý rằng _src kế thừa IQueryable<U> và V kế thừa new();C# LINQ Chọn vấn đề trong chuỗi phương pháp

Tôi đã viết câu lệnh sau, không có lỗi cú pháp.

IQueryable<V> a = from s in _src where (s.Right - 1 == s.Left) select new V(); 

Nhưng nếu tôi đã viết lại nó như sau, các Studio soạn thảo Visual phàn nàn một lỗi trong "Chọn"

IQueryable<V> d = _src.Where(s => s.Right - 1 == s.Left).Select(s=> new V()); 

Các Lỗi là:

The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly. 
Candidates are: 
    System.Collections.Generic.IEnumerable<V> Select<U,V>(this System.Collections.Generic.IEnumerable<U>, System.Func<U,V>) (in class Enumerable) 
    System.Linq.IQueryable<V> Select<U,V>(this System.Linq.IQueryable<U>, System.Linq.Expressions.Expression<System.Func<U,V>>) (in class Queryable) 

bất cứ ai có thể giải thích hiện tượng này, và giải pháp nào là sửa lỗi?

=== Sửa (2010/03/16 05:35) ===

Cảm ơn Mike Hai. Tôi cũng đã thử một ví dụ đơn giản như bạn. Nó hoạt động nhưng điều này không làm trong tôi. Tôi đã đăng mã như sau:

public class NSM<U, V> where U : IQueryable<U> where V : new() 
    { 
    private U _src; 
    public NSM(U source) { _src = source; } 
    public IQueryable<V> LeafNodes 
    { 
     get 
     { 
      return from s in _src where (s.Right - 1 == s.Left) select new V(); 
     } 
    } 
    } 

Tôi muốn hàm LeafNodes được viết lại thành phương pháp chuỗi phương pháp LINQ. Bất kỳ ý tưởng?

+0

Cảm ơn tất cả. Tuyên bố tương đương của câu đầu tiên là gì? – Gnought

+0

Mã bạn đã thêm sẽ không biên dịch trừ khi U là thứ có thuộc tính Phải và Trái. Vì vậy, nó không thể chỉ là một 'IQueryable ' trừ khi có một 'nơi U: ILeftRight' hoặc một cái gì đó. –

+0

Tôi đã tìm ra nó nhờ vào mẫu được cập nhật của bạn. Xem câu trả lời được cập nhật bên dưới. Cảm ơn bạn đã cung cấp thêm thông tin. –

Trả lời

1

Loại _src là gì? Nó có trực tiếp triển khai IQueryable không? Tôi hỏi vì tôi có thể có được một ví dụ đơn giản về những gì bạn đang hiển thị để làm việc.

IQueryable<int> ints = Enumerable.Range(4, 12).AsQueryable(); 

IQueryable<decimal> foo = from s in ints where s > 7 select s * 4.2m; 

IQueryable<decimal> bar = ints.Where(s => s > 7).Select(s => s * 4.2m); 

Cả hai lựa chọn đó đều phù hợp với tôi. Tôi nghĩ rằng nếu trình biên dịch biết rằng ints (hoặc trong trường hợp của bạn _src) là một IQueryable thì nó sẽ gọi quá tải phải. Hay tôi hoàn toàn thiếu một cái gì đó? Có lẽ tôi đã đơn giản hóa nó và mất một chút chi tiết.

CHỈNH SỬA: Mở rộng mục này để sử dụng mã mẫu mới với một số thay đổi.

Bí quyết là Queryable.Select mất một Expression<Func<X, V>>Enumerable.Select mất một Func<X,V> Vì vậy, bạn chỉ cần cung cấp một phiên bản Expression để Select

Hoặc từ mã gốc

Expression<Func<X,V>> expression = s => new V(); 
IQueryable<V> d = _src.Where(s => s.Right - 1 == s.Left).Select(expression); 
1

Các occurres lỗi vì trình biên dịch không thể chọn những gì phương pháp bạn muốn được thực hiện: Phương pháp Select mở rộng cho IEnumerable<T> hoặc Select phương pháp khuyến nông cho IQueryable<T>

1

Vấn đề bạn đang chạy vào là có 2 mục đích sử dụng khác nhau cho Chọn trong ví dụ thứ hai của bạn và bạn có câu lệnh sử dụng thích hợp để truy cập cả hai. Trình biên dịch không thể tìm ra từ câu lệnh mà bạn muốn sử dụng. Bạn phải sử dụng một cuộc gọi chuyên biệt hơn để Chọn hoặc loại bỏ việc sử dụng nếu nó không còn cần thiết, hoặc bằng cách nào đó làm rõ bạn muốn sử dụng cái nào.

+0

Nếu tôi thêm "AsQueryable()" vào Chọn như sau: IQueryable d = _src.Where (s => s.Right - 1 == s.Left) .AsQueryable() Chọn (s => new V()); Lỗi cũng giống nhau. – Gnought

0

Để giải quyết sự mơ hồ cho trình biên dịch sử dụng hàm AsEnumerable()

src.AsEnumerable().Select(s => new V()); 

Hoặc để gán cho IQueryable

IQueryable<V> x = src.AsEnumerable().Select(s => new V()).AsQueryable(); 
+0

Nhưng điều này sẽ trả về IEnumerable thay vì IQueryable . Sửa lỗi mà không thay đổi kiểu trả về là gì? – Gnought

+0

@Tôi nên thêm nó vào bài đăng đã chỉnh sửa. – Cornelius

+0

cảm ơn bạn đã dùng thử. – Gnought

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