首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

LINQ to SQL 進階系列(一):從資料庫映射談起

     編輯:關於.NET

本系列承接入門系列內容,獨立成章。LINQ to SQL 主要解決「資料 ≠ 物件」的阻抗失配問題,建立資料表與類別的一對一映射關係,降低開發門檻,取代傳統 ADO.NET 手工組裝 SQL 與物件映射的繁瑣流程。

LINQ 架構概覽

LINQ(Language Integrated Query)包含三大塊:

  • LINQ to Objects:針對 CLR 物件(記憶體集合)查詢
  • LINQ Enabled ADO.NET:關聯式資料存取,含 LINQ to DataSet、LINQ to SQL(原 DLINQ,支援 SQL Server)、LINQ to Entities(支援 EDM)
  • LINQ to XML:針對 XML 資料操作(原 XLINQ)

LINQ 架構圖

DBML:資料庫標記語言

DBML(Database Markup Language)是 XML 格式的中介描述檔,用於橋接資料庫結構與程式碼產生(支援 C#/VB.NET 差異)。流程為:

Database → DBML → Code

使用 sqlmetal 命令列工具產生 DBML:

sqlmetal /server:YourServer /database:Northwind /dbml:YourDbml.dbml

再由 DBML 產生程式碼:

sqlmetal YourDbml.dbml /code:nwind.cs

OR Designer(Visual Studio 視覺化工具)實際上操作的就是 DBML 檔。部分進階映射(如繼承)需手動修改 DBML。

關聯式資料映射:1:1 與 1:M

資料間基本關聯僅兩種:1:1 與 1:M。以 Northwind 範例資料庫的 Orders(訂單)與 Order Details(訂單明細)為例,關係為 1:M。

One 端(Orders)使用 EntitySet<T>

[Table(Name="Orders")]
public partial class Order : INotifyPropertyChanging, INotifyPropertyChanged {
    [Association(Name="Order_OrderDetail", Storage="_OrderDetails", OtherKey="OrderID")]
    public EntitySet<OrderDetail> OrderDetails {
        get { return this._OrderDetails; }
        set { this._OrderDetails.Assign(value); }
    }
}

EntitySet<TEntity> 實作 IList、ICollection<T>、IEnumerable<T> 等介面,代表「多」端集合。

Many 端(Order Details)使用 EntityRef<T>

[Table(Name="Order Details")]
public partial class OrderDetail : INotifyPropertyChanging, INotifyPropertyChanged {
    private EntityRef<Order> _Order;
    
    [Association(Name="Order_OrderDetail", Storage="_Order", ThisKey="OrderID", IsForeignKey=true)]
    public Order Order {
        get { return this._Order.Entity; }
        set {
            // 雙向同步邏輯:更新雙端導覽屬性與外鍵值
            Order previousValue = this._Order.Entity;
            if (previousValue != value || !this._Order.HasLoadedOrAssignedValue) {
                this.SendPropertyChanging();
                if (previousValue != null) {
                    this._Order.Entity = null;
                    previousValue.OrderDetails.Remove(this);
                }
                this._Order.Entity = value;
                if (value != null) {
                    value.OrderDetails.Add(this);
                    this._OrderID = value.OrderID;
                } else this._OrderID = default(int);
                this.SendPropertyChanged("Order");
            }
        }
    }
}

EntityRef<T> 延遲載入單一參考物件,.Entity 屬性觸發載入。

映射規則總結

  • 1:M:One 端用 EntitySet<T>(集合),Many 端用 EntityRef<T>(單一參考)
  • 1:1:雙端皆用 EntityRef<T>

導覽屬性的型別差異直接反映關聯主體的角色不同。

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