使用 Entity Framework Code First 4.3.1 时,可以创建具有 1 对 1 多重性的关系。也就是说,关系的每一端都有一个实体。
可以将 1 对 1 关系配置为required-required或required-optional ^。但是,当我在两者之间切换时,我看不出有任何区别:
- 生成的数据库模式。我的目标是 SQL Server 2008。
- EF 的运行时行为。
因此,尽管关系被配置为required-required ,但我能够创建没有相应的RequiredDependentAs记录的RequiredPrincipalAs记录。这似乎与HasRequired(...)的文档相矛盾:
配置此实体类型的必需关系。除非指定此关系,否则实体类型的实例将无法保存到数据库中。数据库中的外键将不可为空。
required-required关系实体:
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();
}
我知道我可以将[Required]数据属性添加到RequiredPrincipalA.DependentA和RequiredDependentA.PrincipalA的导航属性中。这将导致 EF 验证阻止上述情况。但是,我不想这样做,因为它还会在更新现有实体时验证导航属性是否已填充。这意味着应用程序必须为每次更新预取关系另一端的实体。
为什么仅在更改required-required和required-optional之间的关系时,我看不到 EF 的行为有任何差异?
^请注意,还支持 optional-optional ,但这不构成我的问题的一部分。配置可选-可选关系时,生成的数据库模式和运行时行为存在明显差异。