2 に答える
独立または外部キー関連付けを使用する理由についての私の意見:
独立団体
長所:
- これは、オブジェクト指向の世界で正しい方法です。オブジェクト指向の世界では、いくつかの魔法のキーではなく、集計内で参照を使用しています。
短所:
- 純粋な POCO では、どちらの場合も参照が null であるため、プリンシパル リレーションが本当に NULL なのか、ロードされていないのかわかりません。これらの 2 つの null を区別するには、コンテキストを確認する必要があります。
EntityObject
これは、プリンシパル エンティティへのすべてのナビゲーション プロパティがReference
、関係に関する追加の詳細を提供するサフィックスが付いた別のプロパティとペアになっている重い基本エンティティでは問題ではありませんでした。 - 独立したアソシエーションを管理する EF の方法は、特に切り離されたオブジェクト グラフをアタッチする場合は非常に複雑です。独立した各関連付けには独自の状態があり、
Modified
状態になることはありません。すべての変更は常に、古いリレーションを削除として設定し、新しいリレーションを追加して作成することで構成されます。これを使用しようとすると、非常に面倒です。 - 独立した関連付けにより、EF の初期化中 (またはビューの事前生成中) にビューの生成が大幅に遅くなることが報告されています。
- 独立した関連付けは、外部キーのみをバインドする必要があるデータ バインド シナリオでは使用するのがはるかに難しくなる可能性があります。
外部キーの関連付け
長所:
- 単純。キー プロパティは管理が簡単で、独立した関連付けに関するすべての問題を解決します - 外部関連付けの状態がない、直接的なデータ バインディング、関係が存在する場合 (キーが null でない) の即時可視性など。
短所:
- それらは概念的に間違っており、EF でそれらを提供することは、オブジェクトの世界からリレーショナルの世界への大きな後退でした。EFv1 と EFv4 の間で大きな重大な変更が発生する可能性があるとしても、正しい解決策は、独立した関連付けの処理方法を改善または変更することであったと今でも信じています。また、まったく異なる動作をする 2 種類の関連付けが存在する現在の状況も気に入りません。明確に定義された動作と、エンティティで公開されるオプションの外部キー プロパティを持つ型は 1 つだけである必要があります。
1 対 1 は常に外部キー アソシエーションであり、多対多は常に独立したアソシエーションであるため、この違いは 1 対多のアソシエーションにのみ関係します。
外部キーの関連付けは、対応するナビゲーション プロパティに加えて、モデルに外部キー プロパティがある場所です。独立した関連付けは、データベースに外部キー列があるが、この列に対応する外部キー プロパティがモデルにない場合です。つまり、NavigationProperty はありますが、外部キー プロパティがないため、その ID 値が何であるかがわかります。関連プロパティは、実際には関連プロパティに移動しません。
Independent Association を持つモデルの例を次に示します (Dependent には外部キーがなく、ナビゲーション プロパティのみであることに注意してください)。
public class Dependent
{
public int Id { get; set; }
[Required]
public Principal PrincipalEntity { get; set; }
}
public class Principal
{
public int Id { get; set; }
public ICollection<Dependent> DependentEntities { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Dependent> Dependents { get; set; }
public DbSet<Principal> Principals { get; set; }
}
次に、同じモデルの例を示しますが、ForeignKey アソシエーションを使用しています (PrincipalEntity_Id プロパティと [ForeignKey()] 属性に注意してください)。
public class Dependent
{
public int Id { get; set; }
public int PrincipalEntity_Id { get; set; }
[Required]
[ForeignKey("PrincipalEntity_Id")]
public Principal PrincipalEntity { get; set; }
}
public class Principal
{
public int Id { get; set; }
public ICollection<Dependent> DependentEntities { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Dependent> Dependents { get; set; }
public DbSet<Principal> Principals { get; set; }
}
データベースは変更されないことに注意してください。基になるデータベースには常に外部キーの列がありましたが、独立した関連付けでは公開されていませんでした。
外部キーの関連付けを使用すると、外部キーの値を変更するだけで関係を更新できます。これは、ナビゲーション プロパティを更新するエンティティを読み込む必要がないため、値がわかっている場合に便利です。