0Pricing
C# Academy · บทเรียน

ต้นไม้นิพจน์ในผู้ให้บริการ LINQ

ดูว่าผู้ให้บริการแปลงนิพจน์เป็นคำสั่งค้นหาอย่างไร

ต้นไม้นิพจน์ในผู้ให้บริการ LINQ เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุผลที่ LINQ ต้องใช้แผนผังนิพจน์

LINQ มีอยู่สองรูปแบบ IEnumerable<T> จะเรียกใช้แลมบ์ดาในหน่วยความจำ ส่วน IQueryable<T> จะรับแลมบ์ดาในรูป แผนผังนิพจน์ เพื่อให้ provider แปลงเป็นภาษาอื่น เช่น SQL

IEnumerable เทียบกับ IQueryable

ความแตกต่างอยู่ที่ชนิดของพารามิเตอร์ IEnumerable.Where รับ Func<T,bool> (ที่คอมไพล์แล้ว) ส่วน IQueryable.Where รับ Expression<Func<T,bool>> (แผนผัง)

using System;
using System.Linq;
using System.Linq.Expressions;

int[] nums = { 1, 2, 3, 4 };
// IEnumerable path: lambda is a compiled delegate
var evens = nums.Where(n => n % 2 == 0);
Console.WriteLine(string.Join(",", evens)); // 2,4

แบบสอบถามยังคงเป็นข้อมูล

เมื่อใช้ IQueryable แลมบ์ดาของคุณจะถูกเก็บไว้ในรูปแผนผังนิพจน์และยังไม่ถูกเรียกใช้ provider จะตรวจสอบแผนผังเพื่อสร้างแบบสอบถาม

using System;
using System.Linq;
using System.Linq.Expressions;

IQueryable<int> q = new[] { 1, 2, 3, 4, 5 }.AsQueryable();
var filtered = q.Where(n => n > 2);
Console.WriteLine(filtered.Expression.NodeType); // Call (a method-call tree)

การตรวจสอบนิพจน์ของแบบสอบถาม

พร็อพเพอร์ตี Expression ของแบบสอบถามที่เรียกใช้ได้จะแสดงแผนผังที่ provider จะแปลง

using System;
using System.Linq;

var q = new[] { 10, 20, 30 }.AsQueryable().Where(x => x >= 20);
Console.WriteLine(q.Expression.ToString().Contains("Where")); // True

การแปลง ไม่ใช่การเรียกใช้

provider อย่าง Entity Framework จะเดินผ่านแผนผังและสร้าง SQL เช่น WHERE Age > 18 predicate ของ C# จะไม่ทำงานบนไคลเอนต์ แต่ฐานข้อมูลจะเป็นผู้ดำเนินการ

บทบาทของ IQueryProvider

IQueryable จะเก็บ IQueryProvider ไว้ เมื่อคุณแจกแจงแบบสอบถาม provider จะได้รับแผนผังนิพจน์และตัดสินใจว่าจะเรียกใช้แบบสอบถามอย่างไร

using System;
using System.Linq;

var q = new[] { 1, 2, 3 }.AsQueryable();
Console.WriteLine(q.Provider.GetType().Name); // EnumerableQuery (the in-memory provider)

การเรียกใช้แบบเลื่อนเวลา

แผนผังจะถูกแปลงและเรียกใช้เมื่อคุณแจกแจงเท่านั้น (เช่น ด้วย ToList หรือ foreach) ก่อนหน้านั้นแผนผังเป็นเพียงข้อมูลล้วน ๆ ที่คุณยังประกอบต่อได้

using System;
using System.Linq;

var q = new[] { 1, 2, 3, 4 }.AsQueryable()
    .Where(n => n > 1)
    .Select(n => n * 10);
// nothing has run yet; now force it:
Console.WriteLine(string.Join(",", q.ToList())); // 20,30,40

การประกอบแบบสอบถาม

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

using System;
using System.Linq;

var baseQuery = new[] { 5, 15, 25, 35 }.AsQueryable();
var q = baseQuery.Where(n => n > 10);
q = q.Where(n => n < 30); // composed: 10 < n < 30
Console.WriteLine(string.Join(",", q.ToList())); // 15,25

สิ่งที่ไม่สามารถแปลงได้

provider สามารถแปลงได้เฉพาะการดำเนินการที่ตนเข้าใจเท่านั้น predicate ที่เรียกใช้เมธอด C# แบบใด ๆ อาจทำให้เกิดข้อผิดพลาดขณะเรียกใช้ เนื่องจากไม่มีสิ่งที่เทียบเท่าใน SQL

การเขียน provider ของคุณเอง

provider แบบกำหนดเองจะใช้งาน IQueryProvider และใช้ ExpressionVisitor เดินผ่านแผนผังเพื่อแปลงแต่ละโหนดเป็นภาษาของแบบสอบถามเป้าหมาย

การนำแนวคิดทั้งหมดมาประกอบกัน

ตัวอย่างนี้แสดงแนวคิดสำคัญว่า แลมบ์ดาเดียวกันเป็นดีลีเกตสำหรับ IEnumerable แต่เป็นแผนผังสำหรับ IQueryable จึงสามารถแปลงได้

using System;
using System.Linq;
using System.Linq.Expressions;

Expression<Func<int, bool>> predicate = n => n > 2;
var data = new[] { 1, 2, 3, 4 };
// IEnumerable needs a delegate:
Console.WriteLine(string.Join(",", data.Where(predicate.Compile()))); // 3,4
// IQueryable accepts the tree directly:
Console.WriteLine(string.Join(",", data.AsQueryable().Where(predicate))); // 3,4

แบบทดสอบสั้น ๆ

ยืนยันความเข้าใจเกี่ยวกับบทบาทของแผนผังนิพจน์ใน LINQ provider

สรุปทบทวน

คุณได้เรียนรู้ว่า LINQ provider ใช้แผนผังนิพจน์อย่างไร

  • IEnumerable ใช้ Func ที่คอมไพล์แล้ว ส่วน IQueryable ใช้แผนผัง Expression<Func>
  • provider จะแปลงแผนผัง (เช่น เป็น SQL) แทนการเรียกใช้แผนผังโดยตรง
  • การเรียกใช้จะเลื่อนออกไปจนกว่าจะมีการแจกแจง
  • ใช้ได้เฉพาะการดำเนินการที่แปลงได้ เมธอดใด ๆ ที่ไม่อยู่ในขอบเขตอาจทำให้เกิดข้อผิดพลาด

คำถามที่พบบ่อย

บทเรียน “ต้นไม้นิพจน์ในผู้ให้บริการ LINQ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ต้นไม้นิพจน์ในผู้ให้บริการ LINQ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ต้นไม้นิพจน์ในผู้ให้บริการ LINQ”

ดูว่าผู้ให้บริการแปลงนิพจน์เป็นคำสั่งค้นหาอย่างไร คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ต้นไม้นิพจน์ในผู้ให้บริการ LINQ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ต้นไม้นิพจน์คืออะไร
  2. การสร้างนิพจน์ด้วยตนเอง
  3. การคอมไพล์และเรียกใช้นิพจน์
  4. ต้นไม้นิพจน์ในผู้ให้บริการ LINQ
← กลับไปที่ C# Academy