2010-05-25 34 views
6

Ok Tôi có những điều sau đây, thiết lập và làm việc tuyệt vời. Những dòng mã này nên thực hiện chuyển đổi từ thực thể DAL (Subsonic) sang ViewModel.Vòng lặp để chuyển đổi LINQ -

IList<ProductOptionModel> OptionsRetData = new List<ProductOptionModel>(); 

    foreach (var CurProductOption in this.ProductOptions) 
    { 
     OptionsRetData.Add(CurProductOption.ToDataModel()); 
    } 

    returnData.Options = OptionsRetData.AsEnumerable(); 

Tôi muốn chuyển đổi điều này thành chỉ số dòng đơn LINQ và đưa ra những điều sau đây.

returnData.Options = this.ProductOptions.Select(o => o.ToDataModel()); 

và tôi nhận được lỗi sau.

Server Error in '/' Application. 
Sequence contains no matching element 

Vậy tại sao stat đầu tiên hoạt động chứ không phải LINQ và tôi có thể thực hiện các bước nào để giải quyết.

Stack Trace

tại System.Linq.Enumerable.First [TSource] (IEnumerable 1 source, Func 2 vị ngữ) tại SubSonic.Extensions.Database.Load [T] (IDataReader RDR, T mục, danh sách 1 ColumnNames) at SubSonic.Extensions.Database.ToEnumerable[T](IDataReader rdr, List 1 COLUMNNAMES) tại SubSonic.Linq.Structure.DbQueryProvider.Execute [T] (QueryCommand 1 query, Object[] paramValues) at lambda_method(Closure) at SubSonic.Linq.Structure.DbQueryProvider.Execute(Expression expression) at SubSonic.Linq.Structure.Query 1.GetEnumerator()

có lẽ đây là để làm với cận âm?

+2

Ngăn xếp cuộc gọi ngoại lệ là gì? – SLaks

+0

Loại trả về của ToDataModel() là gì? –

+0

@Dave Swersky - Loại trả về là ProductOptionModel – LiamB

Trả lời

7

Một khả năng là nó không hoạt động vì bạn đã thay đổi thời gian truy vấn được thực hiện. Thay đổi mã thành mã này thay thế:

returnData.Options = this.ProductOptions.Select(o => o.ToDataModel()).ToList(); 

Điều đó sẽ buộc truy vấn được đánh giá cùng một lúc trước đó.

EDIT: Theo dõi ngăn xếp của bạn đang hiển thị First() được gọi bằng cách nào đó, nhưng chúng tôi không có bất kỳ điều gì về điều đó trong mã bạn đã hiển thị ... bất kỳ ý tưởng nào đang xảy ra?

EDIT: Tôi đã nhận ra sự khác biệt - và tôi ngu ngốc vì không làm như vậy trước đây. Bạn muốn để buộc các chiếu được thực hiện trong quá trình:

returnData.Options = this.ProductOptions 
         .AsEnumerable() 
         .Select(o => o.ToDataModel()) 
         .ToList(); 

Đó thêm cuộc gọi đến AsEnumerable có nghĩa là nó sẽ là quá tải Enumerable.Select mà được gọi là, làm cho nó tương đương với mã gốc của bạn.

+0

@Jon SKeet - Cảm ơn bạn đã trả lời. Thêm các kết quả .ToList() vào cùng một lỗi. (Chỉ trên dòng đó bây giờ chứ không phải là ở chế độ xem) – LiamB

+0

@Jon Skeet - Nghi ngờ kỳ quặc rằng điều này là để làm với SubSonic. Khi tôi không thực hiện cuộc gọi nào tới .irst(); – LiamB

+0

@Pino: Tôi có một ý tưởng khác. Đang chỉnh sửa ... –

0
this.ProductOptions.Select(o => o.ToDataModel()).ToList<ProductOptionModel>(); 
+0

Cùng một vấn đề khi sử dụng dòng ví dụ. – LiamB

-1

Tôi nghĩ rằng bạn cần phải kiểm tra độ dài của this.ProductOptions trước khi tuyên bố LINQ.

Vì vậy, có lẽ (sửa đổi mà không cần kiểm tra cho null):

returnData.Options = (this.ProductOptions.Length > 0) ? this.ProductOptions.Select(o => o.ToDataModel()) : new List<ProductOptionModel>().AsEnumerable(); 
+0

Tại sao vòng lặp lại hoạt động? – LiamB

+0

Có thể không cần phải kiểm tra giá trị rỗng. Vòng lặp hoạt động vì với độ dài 0, luồng của chương trình không bao giờ đi vào vòng lặp. –

+0

Chọn không nên thất bại nếu nó không nhận được bất kỳ giá trị mặc dù ... nó chỉ nên mang lại một kết quả sản phẩm nào. –

2

Như tôi đã nói bạn đang sử dụng phương pháp thứ nhất. bạn có thể muốn thay đổi nó thành FirstOrDefault. nó sẽ được giải quyết. hoặc bạn có thể thay đổi không?

Stack Trace

tại System.Linq.Enumerable.Đầu tiên

+0

như tôi đã nói, tôi không gọi trực tiếp điều đó. Điều này có vẻ là sâu trong các tập tin cận âm. Có thể thats gây ra vấn đề? – LiamB

+0

yep. lý do tại sao điều này xảy ra. chỉnh sửa. có thể sử dụng câu lệnh try catch sẽ sửa lỗi này. bạn đã thử chưa – cem

+0

xem Jon Skeets Trả lời. – LiamB

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