首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

LINQ to SQL 實體類完整指南:屬性對映、DataContext 與關聯

     編輯:關於SqlServer

實體類別與屬性對映

LINQ to SQL 透過屬性將類別對映至資料表。[Table] 標記實體類,[Column] 標記欄位/屬性對映資料行。若名稱不一致,可指定 Name 參數:

[Table(Name="Customers")]
public class Customer
{
    [Column(IsPrimaryKey=true)] public int ID;
    [Column(Name="FullName")] public string Name;
}

主鍵 (IsPrimaryKey) 為維護物件一致性與更新資料庫所必須。建議使用私有欄位搭配公開屬性,並透過 Storage 參數讓 LINQ to SQL 直接讀寫欄位,跳過屬性存取器:

string _name;
[Column(Storage="_name")]
public string Name { get { return _name; } set { _name = value; } }

DataContext 與物件追蹤

DataContext 是查詢與更新的入口。它會追蹤所有實體,確保同一資料列在其生命週期內只有一個實體實例:

var dc = new DataContext("connStr");
Table<Customer> customers = dc.GetTable<Customer>();
Customer cust = customers.OrderBy(c => c.Name).First();
cust.Name = "New Name";
dc.SubmitChanges();

若同一資料列被多次查詢,DataContext 會回傳快取實體,不會重新從資料庫載入最新值,這是為了避免非預期的副作用。

關聯導航屬性

設計工具會自動為資料庫關聯產生導航屬性。一對多關聯中,EntitySet<T> 代表「多」方,EntityRef<T> 代表「一」方,皆支援延遲載入:

[Association(Storage="_Purchases", OtherKey="CustomerID")]
public EntitySet<Purchase> Purchases { get; set; }

// Purchase 端
[Association(Storage="_Customer", ThisKey="CustomerID", IsForeignKey=true)]
public Customer Customer { get; set; }

透過 cust.Purchases 或 purchase.Customer 即可雙向導航,且同一實體在 DataContext 中保證參考相等。

延遲載入與 DataLoadOptions

LINQ to SQL 的延遲載入與本地查詢不同:子查詢出現在 Select 中時,會隨外層查詢一同執行以避免多次往返。若需控制載入行為,可使用 DataLoadOptions:

  • AssociateWith:預先過濾關聯集合(如只載入金額 > 456 的採購單)。
  • LoadWith:立即載入關聯集合,減少資料庫往返。
var options = new DataLoadOptions();
options.LoadWith<Customer>(c => c.Purchases);
options.AssociateWith<Customer>(c => c.Purchases.Where(p => p.Price > 456));
dc.LoadOptions = options;

資料更新與關聯維護

使用 InsertOnSubmit、DeleteOnSubmit 及屬性修改後呼叫 SubmitChanges() 即可完成增刪改,所有變更在單一交易中提交。對 EntitySet 呼叫 Add/Remove 會自動同步外鍵值。設計工具產生的程式碼更會自動維護雙向關聯:

// 直接設定 Purchase.Customer 即可自動加入 Customer.Purchases
new Purchase { Customer = cust, Description = "Bike", Price = 500 };
dc.SubmitChanges();

若要真正刪除子記錄,請對 Table<T> 呼叫 DeleteOnSubmit,而非從 EntitySet 移除(後者只會將外鍵設為 NULL)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved