Entity Framework Code First 4.3.1を使用すると、多重度が1対1の関係を作成できます。つまり、関係の両端に1つのエンティティがあります。
1対1の関係を必須-必須または必須-オプション^に構成することができます。ただし、2つを切り替えても、次の点で違いは見られません。
- 生成されたデータベーススキーマ。SQLServer2008をターゲットにしています。
- EFの実行時の動作。
そのため、関係がrequired-requiredとして構成されているにもかかわらず、対応するRequiredDependentAsレコードなしでRequiredPrincipalAsレコードを作成できます。これは、HasRequired(...)のドキュメントと矛盾しているようです。
このエンティティタイプから必要な関係を構成します。この関係が指定されていない限り、エンティティタイプのインスタンスをデータベースに保存することはできません。データベース内の外部キーはnull不可になります。
必須-必須の関係エンティティ:
public class RequiredPrincipalA
{
public int Id { get; set; }
public virtual RequiredDependentA DependentA { get; set; }
}
public class RequiredDependentA
{
public int Id { get; set; }
public virtual RequiredPrincipalA PrincipalA { get; set; }
}
必須-オプションの関係エンティティ:
public class RequiredPrincipalB
{
public int Id { get; set; }
public virtual OptionalDependentB DependentB { get; set; }
}
public class OptionalDependentB
{
public int Id { get; set; }
public virtual RequiredPrincipalB PrincipalB { get; set; }
}
DbContextとモデル構成:
public class AppContext : DbContext
{
public DbSet<RequiredPrincipalA> PrincipalAs { get; set; }
public DbSet<RequiredDependentA> DependentAs { get; set; }
public DbSet<RequiredPrincipalB> PrincipalBs { get; set; }
public DbSet<OptionalDependentB> DependentBs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<RequiredPrincipalA>()
.HasRequired(o => o.DependentA)
.WithRequiredPrincipal(o => o.PrincipalA);
modelBuilder.Entity<RequiredPrincipalB>()
.HasOptional(o => o.DependentB)
.WithRequired(o => o.PrincipalB);
}
}
テストコード:
Database.SetInitializer(new DropCreateDatabaseAlways<AppContext>());
using (var ctx = new AppContext())
{
ctx.Database.Initialize(force: false);
ctx.PrincipalAs.Add(new RequiredPrincipalA());
ctx.PrincipalBs.Add(new RequiredPrincipalB());
ctx.SaveChanges();
}
RequiredPrincipalA.DependentAおよびRequiredDependentA.PrincipalAのナビゲーションプロパティに[Required]データ属性を追加できることを認識しています。これにより、EF検証が発生し、上記のシナリオが防止されます。ただし、既存のエンティティを更新するときにナビゲーションプロパティが入力されていることも検証するため、これは実行したくありません。つまり、アプリケーションは、更新のたびに、関係のもう一方の端にあるエンティティをプリフェッチする必要があります。
required-requiredとrequired-optionalの関係を変更しただけで、EFの動作に違いが見られないのはなぜですか?
^オプション-オプションもサポートされていることに注意してくださいが、これは私の質問の一部ではありません。オプションとオプションの関係が構成されている場合、生成されるデータベーススキーマと実行時の動作には明らかな違いがあります。