このチュートリアルでは、LINQ to SQL の 関連付けを 使用して、データベース内の外部キーリレーションシップを表す方法について説明します。
注
次の手順では、一部の Visual Studio ユーザー インターフェイス要素の名前や場所がコンピューターに異なる場合があります。 これらの要素は、使用している Visual Studio エディションと使用する設定によって決まります。 詳細については、「IDEのカスタマイズ」を参照してください。
このチュートリアルは、Visual C# 開発設定を使用して作成されました。
前提条件
「チュートリアル: 単純なオブジェクト モデルとクエリ (C#)」を完了している必要があります。 このチュートリアルは、c:\linqtest5 にnorthwnd.mdf ファイルが存在することを含め、そのファイルに基づいています。
概要
このチュートリアルは、次の 3 つの主要なタスクで構成されています。
サンプル Northwind データベースの Orders テーブルを表すエンティティ クラスを追加します。
Customer
クラスとCustomer
クラス間の関係を強化するために、Order
クラスに注釈を追加する。Order
クラスを使用してCustomer
情報の取得をテストするクエリの作成と実行。
テーブル間のリレーションシップのマッピング
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 リレーションシップ全体でのクエリの作成と実行
Order
オブジェクトから直接、または逆の順序でCustomer
オブジェクトにアクセスできるようになりました。 顧客と注文の間に明示的な 結合 は必要ありません。
Order オブジェクトにアクセスするには、Customer オブジェクトを使用します。
次のコードを入力するか、メソッドに貼り付けて、
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); }
F5 キーを押してアプリケーションをデバッグします。
注
db.Log = Console.Out;
をコメント アウトすることで、コンソール ウィンドウで SQL コードを削除できます。コンソール ウィンドウで Enter キーを押してデバッグを停止します。
データベースの厳密に型指定されたビューを作成する
データベースの厳密に型指定されたビューから始める方がはるかに簡単です。 DataContext オブジェクトを厳密に入力することで、GetTableの呼び出しは必要ありません。 厳密に型指定された DataContext オブジェクトを使用する場合は、すべてのクエリで厳密に型指定されたテーブルを使用できます。
次の手順では、データベースの Customers テーブルにマップする厳密に型指定されたテーブルとして Customers
を作成します。
DataContext オブジェクトを厳密に型指定するには
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) { } }
厳密に型指定された
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={custObj.CustomerID}"); } // Freeze the console window. Console.ReadLine();
F5 キーを押してアプリケーションをデバッグします。
コンソール ウィンドウの出力は次のとおりです。
ID=WHITC
コンソール ウィンドウで Enter キーを押してデバッグを停止します。
次のステップ
次のチュートリアル (チュートリアル: データの操作 (C#)) では、データを操作する方法を示します。 このチュートリアルでは、既に完了しているこのシリーズの 2 つのチュートリアルを保存する必要はありません。