ตารางเปรียบเทียบ
| คุณสมบัติ | IEnumerable | IQueryable |
| Namespace | System.Collections | System.Linq |
| Lazy Loading | ไม่รองรับ | รองรับ |
| Query Execution (Database) | Select * แล้ว Filter ใน Memory (Client-side) | Select พร้อม Where ทั้งหมดที่ Server (Server-side) |
| Extension Methods Parameter | Func<T, bool> (Delegate/Function) | Expression<Func<T, bool>> (Expression Tree) |
| เหมาะสำหรับ | In-memory Collection (List, Array) | Database, Remote Data Source |
ตัวอย่าง IEnumerable - Filter ใน Memory
using (var dc = new DbContext())
{
// WHERE ทำงานใน Memory หลังจากดึงข้อมูลทั้งหมดมาแล้ว
IEnumerable<SocialMedia> list = dc.SocialMedias.Where(p => p.Name.StartsWith("T"));
list = list.Take(1); // Take ทำงานใน Memory
}
SQL ที่ Generate (ไม่มี TOP 1)
SELECT [ID], [Name] FROM [SocialMedia] WHERE [Name] LIKE @p0
ตัวอย่าง IQueryable - Filter ที่ Server
using (var dc = new DbContext())
{
// WHERE และ TAKE แปลงเป็น SQL ทั้งหมด
IQueryable<SocialMedia> list = dc.SocialMedias.Where(p => p.Name.StartsWith("T"));
list = list.Take(1); // แปลงเป็น TOP 1 ใน SQL
}
SQL ที่ Generate (มี TOP 1)
SELECT TOP 1 [ID], [Name] FROM [SocialMedia] WHERE [Name] LIKE @p0
เมื่อไหร่ควรใช้ตัวไหน?
ใช้ IEnumerable เมื่อ:
- ข้อมูลอยู่ใน Memory แล้ว (List, Array, Collection)
- ข้อมูลไม่มาก ต้องการ Linq-to-Objects
- ต้องการ Execute ทันที (Immediate Execution)
ใช้ IQueryable เมื่อ:
- Query Database (Entity Framework, LINQ to SQL)
- ข้อมูลเยอะ ต้องการ Filter/Sort/Paging ที่ Server
- ต้องการ Deferred Execution (สร้าง Query ก่อน Execute ทีหลัง)
แปลงระหว่างกันได้
IQueryable<T> query = dbContext.Users.Where(u => u.Active);
IEnumerable<T> inMemory = query.AsEnumerable(); // บังคับ Execute แล้วทำต่อใน Memory
IQueryable<T> backToQuery = inMemory.AsQueryable(); // Wrapper เท่านั้น ไม่กลับเป็น Server-side