2011-11-27 26 views
12

Trong khi thực hiện sau LINQ, tôi nhận được ngoại lệ này:LINQ: ngoại lệ như "Chuỗi không chứa yếu tố"

"Chuỗi không chứa yếu tố"

đang

LINQ:

newGradeRow[rowCnt + 1 + "Grade " + ExamName] = 
     objDataSet.Tables[1].Rows.Cast<DataRow>() 
     .Where(p => Convert.ToDecimal(p["EMG_MARKS_ABOVE"]) <= extSubMarks 
     && extSubMarks <= Convert.ToDecimal(p["EMG_MARKS_BELOW"])) 
     .Select(p => Convert.ToString(p["EMG_GRADE_NAME"])) 
     .First(); 

Bất kỳ ai có thể giúp tôi về điều này không?

+3

Ngoại lệ là rõ ràng - một trong các danh sách bạn đang làm việc trống và không trả lại bất kỳ kết quả nào. – Oded

+2

như tôi đã đề cập trong câu hỏi trong khi thực thi tôi nhận được một ngoại lệ là "Trình tự không chứa các phần tử". bạn có thể vui lòng cho tôi biết lý do tại sao tôi nhận được ngoại lệ hoặc những gì là sai trong mã. tôi mới vào. –

+2

Tôi nghĩ bộ sưu tập của bạn không có mặt hàng nào. * Bạn nghĩ gì bạn nên làm gì? Câu hỏi này là một bài tập trong suy nghĩ cơ bản. – Amy

Trả lời

0

objDataSet.Tables[1] trống?

Có lẽ dữ liệu nằm trong số objDataSet.Tables[0]?

Dù bằng cách nào, bạn có thể thử nghiệm với objDataSet.Tables.Count() > 0

Bạn có thể làm tương tự cho dòng: objDataSet.Tables[1].Rows.Count() > 0

+2

Hoặc không có phần tử nào vượt qua bộ lọc 'Where'. Ngoại lệ được nâng lên bởi 'Đầu tiên' khi nó được đưa ra một danh sách trống. –

+0

oh vâng. cảm ơn. –

39

Trường hợp ngoại lệ được ném trong cuộc gọi First phương pháp nếu chuỗi rỗng vì nó được ghi trong documentation . Trong trường hợp này, tốt hơn là sử dụng phương thức FirstOrDefault - nó sẽ trả về giá trị mặc định (trong trường hợp cụ thể là null) và không có ngoại lệ nào được ném.

1

Bạn nên cẩn thận về điều này: Biểu thức/truy vấn LINQ không chứa bất kỳ bản ghi nào sau đó bạn không thể sử dụng Single()First().

On the place Single() in your Lambda expression use FirstOrDefault() 
2

Rất khó để nói chuỗi nào không có yếu tố khi bạn có nhiều chuỗi cùng nhau trong cùng một dòng mã. Hãy thử phá vỡ mã của bạn xuống nhiều dòng và sau đó gỡ lỗi nó. Điều này sẽ làm cho nó dễ đọc hơn.

var myVariable = objDataSet.Tables[1]; 
var myEntity = myVariable.Rows.Cast<DataRow>().Where(
    p => Convert.ToDecimal(p["EMG_MARKS_ABOVE"]) <= extSubMarks 
    && extSubMarks <= Convert.ToDecimal(p["EMG_MARKS_BELOW"])) 
    .Select(p => Convert.ToString(p["EMG_GRADE_NAME"])).FirstOrDefault(); 

Nếu vấn đề là ở đâu đó trong biểu Lambda của bạn, bạn có thể muốn phá vỡ nó ra thành một vòng lặp foreach (chỉ vì lợi ích của gỡ lỗi & có quyền truy cập vào các dữ liệu bên trong cửa sổ ngay lập tức của VS).

+1

Bạn đã thay đổi cuộc gọi cuối cùng thành 'FirstOrDefault()' sẽ loại bỏ ngoại lệ nhưng bạn chưa đề cập đến điều đó là hơi lạ. –

+0

Sai lầm của tôi. Tôi thích sử dụng phương thức mở rộng FirstOrDefault() trên First() để xử lý ngoại lệ tốt hơn. Sau đó bạn có thể kiểm tra các giá trị rỗng sau đó trước khi tiếp tục. –

6

Bắt đầu bằng cách chia nhỏ. Mã hiện tại của bạn không cung cấp cho trình gỡ lỗi.

var r1 = objDataSet.Tables[1].Rows; 
var r2 = r1.Cast<DataRow>(); 
System.Diagnostics.Debug.Print("r2: {0}", r2.Count()); 
var r3 = r2.Where(p => Convert.ToDecimal(p["EMG_MARKS_ABOVE"]) <= extSubMarks 
      && extSubMarks <= Convert.ToDecimal(p["EMG_MARKS_BELOW"])); 
System.Diagnostics.Debug.Print("r3: {0}", r3.Count()); 
var r4 = r3.Select(p => Convert.ToString(p["EMG_GRADE_NAME"])); 
var r5 = r4.First(); 

newGradeRow[rowCnt + 1 + "Grade " + ExamName] = r5; 
+0

Trong khi mã là một chút khó hiểu, nó là khá rõ ràng rằng điều ONLY đó sẽ ném ngoại lệ đó là cuộc gọi đến đầu tiên() mà đòi hỏi 1 hoặc nhiều yếu tố. –

+0

@BenRobinson, Đồng ý, nhưng nó có trống trước hoặc sau 'Where()'? Tôi muốn biết. –

+3

Đủ công bằng, nhưng tôi khuyên bạn nên đề cập rằng đó là lời kêu gọi 'Đầu tiên()' để ném và giải thích sự khác biệt giữa 'First()' và 'FirstOrDefault()' –

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