查詢語法 (IQueryable) 僅建立描述,實際 SQL 於 列舉時 (foreach、ToList、Count 等) 才發送。重複列舉會重複查詢:
var q = from c in ctx.Customers select c;
foreach (var c in q) Console.Write(c.CustomerID); // SQL #1
foreach (var c in q) Console.Write(c.ContactName); // SQL #2 再查一次
// 建議:var list = q.ToList(); 再對 list 操作
優點:可像拼接 SQL 般組合查詢 (OrderBy、Where 等)。
var opts = new DataLoadOptions();
opts.LoadWith<Product>(p => p.Order_Details);
ctx.LoadOptions = opts;
// 產生 LEFT OUTER JOIN 單一 SQL,避免 N+1 查詢
opts.AssociateWith<Product>(p => p.Order_Details.Where(od => od.Quantity > 80));
// JOIN 時帶入 WHERE Quantity > 80
同一 DataContext 內,依主鍵查詢單筆 (Single) 會先查快取,不發 SQL:
var c1 = ctx.Customers.Single(c => c.CustomerID == "ANATR");
c1.ContactName = "zhuye";
var c2 = ctx.Customers.Single(c => c.CustomerID == "ANATR"); // 直接回傳快取物件
Console.WriteLine(c2.ContactName); // 輸出 zhuye (未 SubmitChanges)
注意:若使用預存程序更新,快取與資料庫可能不一致。
跨 Context 傳遞實體需 Attach。主鍵標記 IsVersion=true 可啟用樂觀平行存取:
[Column(..., IsPrimaryKey=true, IsVersion=true)] public string CustomerID { get; set; }
// 更新
var c = new Customer { CustomerID="ALFKI", ContactName="zhuye", CompanyName="1111" };
ctx.Customers.Attach(c, true); // true = 視為已修改
ctx.SubmitChanges();
產生 WHERE (PK=@p0) AND (PK=@p1) 確保版本一致。