ลำดับไม่มีองค์ประกอบ?


131

ฉันกำลังใช้แบบสอบถามเดียวในสองที่เพื่อรับแถวจากฐานข้อมูล

BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == ID
                 select p).Single();

แบบสอบถามนี้ใช้ได้ดีเมื่อเรียกแถวเพื่อใส่ข้อมูลลงในกล่องข้อความ แต่จะส่งกลับข้อผิดพลาด "ลำดับที่ไม่มีองค์ประกอบ" เมื่อใช้เพื่อดึงข้อมูลแถวเพื่อแก้ไขและนำกลับไปที่ฐานข้อมูล ฉันไม่เข้าใจว่าเหตุใดจึงอาจพบแถวที่เหมาะสมในอินสแตนซ์หนึ่ง แต่ไม่พบแถวอื่น

(ใช้ ASP.NET MVC และ LINQ)


18
คุณต้องใช้ SingleOrDefault มันจะคืนค่าว่างถ้าไม่มีรายการกลับ
Mahmoud Farahat

ข้อผิดพลาดบอกว่าไม่พบรายการใด ๆ ใน dc.BlogPosts ซึ่งตรงกับค่าของ ID ID ไม่มีค่าหรือรายการในรายการของคุณมีรายการนั้น ใช้ SingleOrDefault หรือ FirstOrDefault สิ่งเหล่านี้จะส่งคืนอ็อบเจ็กต์ null หากไม่พบไอเท็มแทนที่จะเป็นข้อผิดพลาด
prd82

คำตอบ:


32

ใส่เบรกพอยต์ในบรรทัดนั้นหรือ Debug พิมพ์ก่อนทั้งสองกรณีและดูว่ามี ID อะไรบ้าง


2
จากนั้นพบว่าด้วยเหตุผลบางประการ ID และวันที่จะถูกส่งเป็น null \ new (0000-0000) จากหน้าแก้ไข หน้าเว็บนี้พิมพ์ผิดเป็น BlogPost ในหน้าแก้ไขฉันมีเฉพาะกล่องข้อความสำหรับชื่อและเนื้อหาไม่มีการใส่ ID และวันที่ในหน้าเลย นี่อาจเป็นสาเหตุที่ทำให้มันส่งต่อเป็น null \ new?

2
คุณคาดหวังว่า ID จะมาจากไหน?
Ryan Lundy

8
ในมุมกลับฉันไม่แน่ใจจริงๆ> _ <ปัญหาโง่จริงๆ

368

จาก " Fixing LINQ Error: Sequence ไม่มีองค์ประกอบ ":

เมื่อคุณได้รับข้อผิดพลาด LINQ ว่า "ลำดับไม่มีองค์ประกอบ" นี้ปกติจะเป็นเพราะคุณกำลังใช้First()หรือSingle()คำสั่งมากกว่าและFirstOrDefault()SingleOrDefault()

สิ่งนี้อาจเกิดจากคำสั่งต่อไปนี้:

  • FirstAsync()
  • SingleAsync()
  • Last()
  • LastAsync()
  • Max()
  • Min()
  • Average()
  • Aggregate()

3
สิ่งนี้ช่วยแก้ปัญหาของฉันได้ ขอบคุณสำหรับลิงค์!
CountMurphy

5
ที่สมบูรณ์แบบ! ctx.Rosters.First(c => c.RosterAccess == accCode);<- เสียctx.Rosters.FirstOrDefault(c => c.RosterAccess == accCode);<- WORKED
ราวีราม

2
ในกรณีของฉันฉันทำMaxตามลำดับที่ว่างเปล่า
guzart

1
ตอนนี้เรารู้แล้วว่าการโหวตแต่ละครั้งมีน้ำหนัก (ในขณะนี้) 31.25 ปอนด์
บีเคลย์แชนนอน

2
คุณแน่ใจหรือไม่ว่าLastOrDefault()สามารถทำให้เกิดข้อผิดพลาดนั้นได้ ทำไม? ฉันคิดว่า "OrDefault" คือประเด็นทั้งหมด
Robouste

23

โปรดใช้

.FirstOrDefault()

เพราะถ้าในแถวแรกของผลลัพธ์ไม่มีข้อมูลคำสั่งนี้จะไปที่ข้อมูลเริ่มต้น


2
ในกรณีของการโทรแบบ async ให้ใช้. FirstOrDefaultAsync ();
Andrea Girardi

12

ที่IDนี่คืออะไร? โดยเฉพาะอย่างยิ่งมันเป็นตัวแปรท้องถิ่นหรือไม่? มีปัญหาเกี่ยวกับขอบเขต / การจับภาพซึ่งหมายความว่าคุณอาจต้องการใช้สำเนาตัวแปรที่สองสำหรับข้อความค้นหาเท่านั้น:

var id = ID;
BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == id
                 select p).Single();

นอกจากนี้ยัง; ถ้านี่คือ LINQ-to-SQL ดังนั้นในเวอร์ชันปัจจุบันคุณจะมีพฤติกรรมที่ดีขึ้นเล็กน้อยหากคุณใช้แบบฟอร์ม:

var id = ID;
BlogPost post = dc.BlogPosts.Single(p => p.BlogPostID == id);

ID คือ GUID ที่ส่งผ่านเป็นอาร์กิวเมนต์

10

สิ่งนี้จะช่วยแก้ปัญหา

var blogPosts = (from p in dc.BlogPosts
             where p.BlogPostID == ID
             select p);
if(blogPosts.Any())
{
  var post = post.Single();
}

8

นอกเหนือจากสิ่งอื่น ๆ ที่ได้กล่าวไปแล้วคุณสามารถโทรDefaultIfEmpty()ก่อนโทรSingle()ได้ สิ่งนี้จะช่วยให้แน่ใจว่าลำดับของคุณมีบางสิ่งและด้วยเหตุนี้จึงหลีกเลี่ยง InvalidOperationException "ลำดับไม่มีองค์ประกอบ" ตัวอย่างเช่น:

BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == ID
                 select p).DefaultIfEmpty().Single();

2

ฉันมีสถานการณ์ที่คล้ายกันกับฟังก์ชันที่คำนวณค่าเฉลี่ย

ตัวอย่าง:

ws.Cells[lastRow, startingmonths].Value = lstMediaValues.Average();

แก้ไขกรณี:

ws.Cells[lastRow, startingmonths].Value = lstMediaValues.Count == 0 ? 0 : lstMediaValues.Average();

1

สาเหตุของข้อผิดพลาด:

  1. แบบสอบถามfrom p in dc.BlogPosts where p.BlogPostID == ID select pส่งคืนลำดับ

  2. Single() พยายามดึงองค์ประกอบจากลำดับที่ส่งคืนในขั้นตอนที่ 1

  3. ตามข้อยกเว้น - ลำดับที่ส่งคืนในขั้นตอนที่ 1 ไม่มีองค์ประกอบ

  4. Single () พยายามดึงข้อมูลองค์ประกอบจากลำดับที่ส่งคืนในขั้นตอนที่ 1 ซึ่งไม่มีองค์ประกอบ

  5. เนื่องจากSingle()ไม่สามารถดึงองค์ประกอบเดียวจากลำดับที่ส่งคืนในขั้นตอนที่ 1 จึงเกิดข้อผิดพลาด

การแก้ไข:

ตรวจสอบให้แน่ใจว่าแบบสอบถาม (from p in dc.BlogPosts where p.BlogPostID == ID select p)

ส่งคืนลำดับที่มีอย่างน้อยหนึ่งองค์ประกอบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.