LINQ (Language Integrated Query) เป็นฟีเจอร์ของ C# ที่ช่วยให้เราสามารถเขียนโค้ดที่จัดการกับข้อมูลในรูปแบบของ Collection, Database, XML, หรือ Object ได้อย่างมีประสิทธิภาพและอ่านง่ายขึ้น

โดย LINQ มีความสามารถที่ช่วยให้เราสามารถ กรอง (Filter), จัดเรียง (Sort), รวม (Aggregate), และเปลี่ยนแปลง (Transform) ข้อมูล ได้ในรูปแบบที่กระชับและเข้าใจง่ายกว่าการใช้ foreach และ for ปกติ
แต่อย่างไรก็ดี ควรใช้ LINQ อย่างระมัดระวัง เนื่องจากบางคำสั่งอาจมีผลต่อ Performance โดยเฉพาะบนมือถือ เช่น คำสั่งที่ใช้การจัดเรียง (OrderBy) หรือคำสั่งที่สร้างอ็อบเจกต์ใหม่บ่อย ๆ เช่น การ Select หรือ Where บน List ขนาดใหญ่
โครงสร้างพื้นฐานของ LINQ
- Query Syntax (สไตล์คล้าย SQL)
- Method Syntax (ใช้ Lambda Expression)
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class LinqDemo : MonoBehaviour
{
void Start()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
// วิธีที่ 1 Query Syntax
var evenNumbersQuery = from num in numbers
where num % 2 == 0
select num;
// วิธีที่ 2 Method Syntax (Lambda Expression)
var evenNumbersMethod = numbers.Where(num => num % 2 == 0);
// แสดงผลลัพธ์จากวิธีที่ 1
Debug.Log("Query Syntax: " + string.Join(", ", evenNumbersQuery));
// แสดงผลลัพธ์จากวิธีที่ 2
Debug.Log("Method Syntax: " + string.Join(", ", evenNumbersMethod));
}
}
ค้นหาข้อมูลใน List หรือ Array
Where() → คัดกรองข้อมูลตามเงื่อนไข
FirstOrDefault() / First() → คืนค่าตัวแรกที่ตรงกับเงื่อนไข (ถ้าไม่มีค่า First() จะ Error แต่ FirstOrDefault() จะคืนค่า null หรือค่าเริ่มต้น)
LastOrDefault() / Last() → คืนค่าตัวสุดท้ายที่ตรงกับเงื่อนไข
SingleOrDefault() / Single() → คืนค่าตัวเดียวเท่านั้น ถ้าพบมากกว่าหนึ่งตัวจะ Error
List<int> numbers = new List<int> { 10, 20, 30, 40, 50 };
var result = numbers.Where(n => n > 25).ToList();
int firstNumber = numbers.FirstOrDefault(n => n > 25);
int lastNumber = numbers.LastOrDefault(n => n > 25);
int singleNumber = numbers.SingleOrDefault(n => n == 40);
Debug.Log( reult );
Debug.Log( firstNumber );
Debug.Log( lastNumber );
Debug.Log( singleNumber );
การจัดเรียงข้อมูล
OrderBy() → เรียงลำดับจากน้อยไปมาก
OrderByDescending() → เรียงลำดับจากมากไปน้อย
List<int> numbers = new List<int> { 5, 2, 8, 1, 9, 11, 3, 4, 7 };
var sortedNumbers = numbers.OrderBy(n => n).ToList();
var sortedDescNumbers = numbers.OrderByDescending(n => n).ToList();
Debug.Log( startedNumbers);
Debug.Log( startedDescNumbers);
การแปลงข้อมูล
Select() → ใช้สำหรับแปลงค่าหรือเลือกเฉพาะบางฟิลด์
SelectMany() → ใช้เมื่อแต่ละรายการมี List ซ้อนอยู่ภายใน
List<string> names = new List<string> { "Lisa", "Simone", "Lara" };
var upperNames = names.Select(n => n.ToUpper()).ToList();
Debug.Log( names );
Debug.Log( upperNames);
การรวมข้อมูล
Sum() → ผลรวมของค่าทั้งหมด
Average() → ค่าเฉลี่ย
Count() → จำนวนข้อมูล
Max() / Min() → ค่าสูงสุด/ต่ำสุด
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 100, 200, 300, 400, 500 };
int sum = numbers.Sum();
double avg = numbers.Average();
int count = numbers.Count();
int max = numbers.Max();
int min = numbers.Min();
Debug.Log( sum );
Debug.Log(avg);
Debug.Log(count);
Debug.Log(min);
Dbug.Log(max);
ตรวจสอบข้อมูล
Any() → คืนค่า true ถ้ามีอย่างน้อยหนึ่งรายการที่ตรงเงื่อนไข
All() → คืนค่า true ถ้าทุกตัวตรงเงื่อนไข
List<int> numbers = new List<int> { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 };
bool hasEven = numbers.Any(n => n % 2 == 0);
bool allGreaterThanZero = numbers.All(n => n > 0);
Debug.Log( hasEven );
Debug.Log( allGreaterThanZero);
LINQ กับ GameObject
สามารถใช้ LINQ เพื่อค้นหาและจัดการ GameObject ได้ดังตัวอย่างต่อไปนี้เป็นการปิดการทำงานศัตรูที่มี HP น้อยกว่า 10
using System.Linq;
using UnityEngine;
public class LinqWithGameObjects : MonoBehaviour
{
void Start()
{
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
// หาศัตรูที่มีค่า HP น้อยกว่า 10
var weakEnemies = enemies
.Where(e => e.GetComponent<Enemy>().health < 10)
.ToList();
// ปิดการใช้งานศัตรูที่อ่อนแอทั้งหมด
weakEnemies.ForEach(e => e.SetActive(false));
}
}
สรุป
- LINQ ช่วยให้เขียนโค้ดได้กระชับและอ่านง่ายขึ้น
- สามารถใช้ Where(), Select(), OrderBy(), Sum(), Any() และอื่นๆ กับข้อมูลต่างๆ ได้
- ใช้ LINQ กับ GameObject ได้ แต่ต้องระวัง Performance
- ใช้กับข้อมูลขนาดเล็ก เช่น ค้นหา GameObject, คำนวณค่าจาก List
- หลีกเลี่ยงการใช้ LINQ ใน Update() หรือ FixedUpdate() หรือ Loop ขนาดใหญ่ (มีการวนรอบหลายรอบมาก ๆ) เพราะอาจเกิด Garbage Collection และทำให้เกมกระตุก