พฤติกรรมของ LINQ เมื่อไม่พบข้อมูล
LINQ (Language-Integrated Query) เป็นเทคโนโลยีที่รวมความสามารถในการ query เข้าไปในภาษา C# โดยตรง ใช้งานได้กับ SQL Server, XML, ADO.NET DataSet และคอลเลกชันที่ implement IEnumerable หรือ IEnumerable<T>
สรุปพฤติกรรมของเมธอด LINQ ต่างๆ เมื่อผลลัพธ์ว่าง
| เมธอด | พฤติกรรมเมื่อว่าง | โยน Exception? |
|---|---|---|
First() | โยน InvalidOperationException | ใช่ |
FirstOrDefault() | คืนค่า default(T) (null สำหรับ reference type, 0 สำหรับ int, ฯลฯ) | ไม่ |
Single() | โยน Exception (ถ้ามี 0 หรือ มากกว่า 1 รายการ) | ใช่ |
SingleOrDefault() | คืนค่า default(T) | ไม่ |
Last() | โยน Exception | ใช่ |
LastOrDefault() | คืนค่า default(T) | ไม่ |
ToList() | คืนค่า List<T> ว่าง (Count = 0) | ไม่ |
ToArray() | คืนค่า Array ว่าง (Length = 0) | ไม่ |
Count() | คืนค่า 0 | ไม่ |
Any() | คืนค่า false | ไม่ |
All() | คืนค่า true (vacuous truth) | ไม่ |
ตัวอย่าง: ใช้ Where + ToList()
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public static void Main()
{
List<string> list = new List<string> { "a" };
// ไม่มีข้อมูลตรงเงื่อนไข
IEnumerable<string> result = list.Where(x => x == "ABC").ToList();
Console.WriteLine($"จำนวน: {result.Count()}"); // 0
foreach (var item in result)
{
Console.WriteLine(item); // ไม่พิมพ์อะไรเลย
}
}
}
ผลลัพธ์:
จำนวน: 0
ตัวอย่าง: ใช้ First() vs FirstOrDefault()
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3 };
// FirstOrDefault - ปลอดภัย
int firstOrDefault = numbers.FirstOrDefault(x => x > 10);
Console.WriteLine($"FirstOrDefault: {firstOrDefault}"); // 0
// First - โยน Exception
try
{
int first = numbers.First(x => x > 10);
Console.WriteLine($"First: {first}");
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"First โยน Exception: {ex.Message}");
}
}
}
ผลลัพธ์:
FirstOrDefault: 0 First โยน Exception: Sequence contains no matching element
แนวทางปฏิบัติที่แนะนำ
- ใช้
FirstOrDefault(),SingleOrDefault(),LastOrDefault()เมื่อไม่แน่ใจว่ามีข้อมูล - ใช้
Any()ตรวจสอบก่อนเรียกFirst()หากต้องการโยน exception เอง ToList()และToArray()ปลอดภัยเสมอ คืนคอลเลกชันว่างแทน null- ใน LINQ to SQL / Entity Framework: พฤติกรรมเหมือนกันแต่ query จะ execute ที่ database