LinqToSQL と 1 対 1 の関係を定義する
-
02-07-2019 - |
質問
既存の多言語データベースを使用して LinqToSQL を試していますが、かなり重要な 1 対 1 の関係をマッピングする際に問題が発生しているため、データベース設計に対してこの機能を間違って使用しているのではないかと考えています。
カテゴリとカテゴリ詳細という 2 つのテーブルがあるとします。カテゴリには、CategoryId (PK)、ParentId、および TemplateId が含まれます。CategoryDetail には、CategoryId (FK)、LanguageId、タイトル、および説明 (適切な言語で) と、CategoryId と LanguageId の組み合わせ PK が含まれます。
これらのテーブルを LinqToSQL デザイナーにドラッグ アンド ドロップすると、結果として得られるオブジェクト モデルには、CategoryDetail オブジェクトのコレクションを含む Category が含まれますが、これは本来あり得ないことです。DataContext レベルで LanguageId でフィルターできるようにしたいと考えています。これは、すべての言語バージョンが category.CategoryDetails 内にカプセル化されるのではなく、カテゴリ全体が category.CategoryDetail 内にカプセル化されることを意味します。
このデータベースは私の古いオブジェクト ライブラリ (昔ながらのカスタム BOL および DAL) では問題なく動作しましたが、LinqToSQL で必要な結果を得るにはこれを変更する必要があるのではないかと心配しています。
この関係 (および言語フィルタリング) をできるだけシームレスにする最善の方法は何でしょうか?
解決
関連付けのプロパティを表示できます。(関連付けを表す線を右クリックしてプロパティを表示します。) プロパティにより、それが 1 対 1 の関係であるか、1 対多の関係であるかがわかります。これは、単一エンティティの関連付け (1 対 1) またはエンティティ セットの関連付け (1 対多) のいずれかを行うことによってコードに反映されます。
他のヒント
真の1対1ではないと想定する必要があります。Cat の詳細テーブルに CatID と Lang ID の PK があるようです。そうすれば、コレクションを作成する理由が説明されます。CatDetails テーブルの PK について言及していないので、間違っている可能性があります。
編集:CatID と Lang ID の Pk を組み合わせると 1:m の関係になり、Linq to SQL は実際に正しい動作をしています。真の 1:1 になる唯一の方法は、cat テーブルにも lang ID があり、それが FK の一部である場合です。何をしたいのか、あるいはそれをどのように実装するのかを再考する必要があるかもしれません。
LINQ to SQL はデータベース構造を直接モデル化していると思います。テーブルが 2 つあるので、オブジェクトが 2 つ作成されます。
LINQ to Entities をご覧になったことがありますか。これにより、データベース構造の上に別のレイヤーを作成して、より読みやすいクラスを作成できます。
1 対 1 の関係がないため、マッピングだけでは必要な機能は提供されません。ただし、そのジョブを実行する親の自動生成クラスにメソッドを提供するのは簡単です。
public partial class Category
{
public IEnumerable<CategoryDetail> GetDetailsByLanguage(string langID)
{
return this.CategoryDetails.Where(c => c.LangID == langID);
}
}