ต้นไม้นิพจน์ในผู้ให้บริการ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ต้นไม้นิพจน์คืออะไร
- การสร้างนิพจน์ด้วยตนเอง
- การคอมไพล์และเรียกใช้นิพจน์
- ต้นไม้นิพจน์ในผู้ให้บริการ LINQ