逐步解說:跨關聯性查詢 (C#) (LINQ to SQL)

更新: November 2007

此逐步解說會示範如何使用 LINQ to SQL「關聯」(Association) 來表示資料庫中的外部索引鍵關聯性 (Relationship)。

注意事項:

您的電腦可能會在下列說明中,以不同名稱或位置顯示某些 Visual Studio 使用者介面項目。您所擁有的 Visual Studio 版本以及使用的設定會決定這些項目。如需詳細資訊,請參閱 Visual Studio 設定

本逐步解說是使用 Visual C# 開發設定撰寫。

必要條件

您必須已完成逐步解說:簡單的物件模型和查詢 (C#) (LINQ to SQL)。此逐步解說建立於該逐步解說之上,其中包含出現在 c:\linqtest5 中的 northwnd.mdf 檔。

概觀

此逐步解說包含三項主要工作:

  • 加入實體類別,以表示 Northwind 範例資料庫中的 Orders 資料表。

  • 補充 Customer 類別的附註,以加強 Customer 和 Order 類別之間的關聯性。

  • 建立和執行查詢,以測試使用 Customer 類別取得 Order 資訊。

跨資料表對應關聯性

在 Customer 類別定義之後,建立包含下列程式碼的 Order 實體類別定義,這表示 Order.Customer 為 Customer.CustomerID 的外部索引鍵。

若要加入 Order 實體類別

  • 在 Customer 類別之後輸入或貼上下列程式碼:

    [Table(Name = "Orders")]
    public class Order
    {
        private int _OrderID = 0;
        private string _CustomerID;
        private EntityRef<Customer> _Customer;
        public Order() { this._Customer = new EntityRef<Customer>(); }
    
        [Column(Storage = "_OrderID", DbType = "Int NOT NULL IDENTITY",
        IsPrimaryKey = true, IsDbGenerated = true)]
        public int OrderID
        {
            get { return this._OrderID; }
            // No need to specify a setter because IsDBGenerated is
            // true.
        }
    
        [Column(Storage = "_CustomerID", DbType = "NChar(5)")]
        public string CustomerID
        {
            get { return this._CustomerID; }
            set { this._CustomerID = value; }
        }
    
        [Association(Storage = "_Customer", ThisKey = "CustomerID")]
        public Customer Customer
        {
            get { return this._Customer.Entity; }
            set { this._Customer.Entity = value; }
        }
    }
    

加入 Customer 類別的附註

在這個步驟中,您會加入 Customer 類別的附註,指出其與 Order 類別的關聯性 (此加入動作並非絕對必要,因為定義任一方向的關聯性就足以建立連結。但加入此附註確實可讓您輕易地以任一方向巡覽物件)。

若要加入 Customer 類別的附註

  • 將下列程式碼輸入或貼到 Customer 類別中:

    private EntitySet<Order> _Orders;
    public Customer()
    {
        this._Orders = new EntitySet<Order>();
    }
    
    [Association(Storage = "_Orders", OtherKey = "CustomerID")]
    public EntitySet<Order> Orders
    {
        get { return this._Orders; }
        set { this._Orders.Assign(value); }
    }
    

建立和執行客戶-訂單關聯性的查詢

您現在可以直接從 Customer 物件存取 Order 物件,反之亦然。您不需要客戶和訂單之間的明確「聯結」(Join)。

若要使用 Customer 物件存取 Order 物件

  1. 將下列程式碼輸入或貼到 Main 方法,進而修改此方法:

    // Query for customers who have placed orders.
    var custQuery = 
        from cust in Customers
        where cust.Orders.Any()
        select cust;
    
    foreach (var custObj in custQuery)
    {
        Console.WriteLine("ID={0}, Qty={1}", custObj.CustomerID,
            custObj.Orders.Count);
    }
    
  2. 按 F5 對應用程式進行偵錯。

    注意事項:

    您可以將 db.Log = Console.Out; 標記為註解,以便在主控台視窗中排除 SQL 程式碼。

  3. 在主控台視窗中按 Enter 鍵,以停止偵錯。

建立資料庫的強型別檢視

從資料庫的強型別 (Strongly Typed) 檢視著手會容易許多。透過建立強型別 DataContext 物件,您就不需要呼叫 GetTable。當您使用強型別 DataContext 物件時,可以在所有查詢中使用強型別資料表。

在下列步驟中,您會將 Customers 建立為強型別資料表,以對應資料庫中的 Customers 資料表。

若要建立強型別 DataContext 物件

  1. 在 Customer 類別宣告之上加入下列程式碼。

    public class Northwind : DataContext
    {
        // Table<T> abstracts database details per table/data type.
        public Table<Customer> Customers;
        public Table<Order> Orders;
    
        public Northwind(string connection) : base(connection) { }
    }
    
  2. 修改 Main 方法以使用強型別 DataContext,如下所示:

    // Use a connection string.
    Northwind db = new Northwind(@"C:\linqtest5\northwnd.mdf");
    
    // Query for customers from Seattle. 
    var custQuery =
        from cust in db.Customers
        where cust.City == "Seattle"
        select cust;
    
    foreach (var custObj in custQuery)
    {
        Console.WriteLine("ID={0}", custObj.CustomerID);
    }
    // Freeze the console window.
    Console.ReadLine();
    
  3. 按 F5 對應用程式進行偵錯。

    主控台視窗輸出為:

    ID=WHITC

  4. 在主控台視窗中按 Enter 鍵,以停止偵錯。

後續步驟

下一個逐步解說 (逐步解說:操作資料 (C#) (LINQ to SQL)) 會示範如何管理資料。該逐步解說並不要求您儲存這系列中已完成的兩個逐步解說。

請參閱

概念

從逐步解說學習 (LINQ to SQL)