实体框架代码首先一对一要求 - 必需的关系

Mat*_*oks 9 entity-framework

使用Entity Framework Code First 4.3.1时,可以创建多重1对1的关系.也就是说,关系的每一端都有一个实体.

可以将所需的 1对1关系配置为必需必需 - 可选 ^.但是,当我在两者之间切换时,我看不出任何差异:

  • 生成数据库架构.我的目标是SQL Server 2008.
  • EF的运行时行为.

因此,我能够创建一个RequiredPrincipalAs记录而没有相应的RequiredDependentAs记录,尽管关系被配置为required-required.这似乎与HasRequired(...)的文档相矛盾:

从此实体类型配置所需的关系.除非指定了此关系,否则无法将实体类型的实例保存到数据库.数据库中的外键将不可为空.

http://msdn.microsoft.com/en-us/library/gg671317

时需提供-关系的实体:

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; }
}
Run Code Online (Sandbox Code Playgroud)

要求,可选的关系实体:

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; }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

测试代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以在RequiredPrincipalA.DependentARequiredDependentA.PrincipalA的导航属性中添加[Required]数据属性.这将导致EF验证以防止上述情况.但是,我不想这样做,因为它还验证了在更新现有实体时填充的导航属性.这意味着应用程序必须为每次更新预先获取关系另一端的实体.

为什么在改变required-requiredrequired-optional之间的关系时,我看不出EF的行为有什么不同?

^ 请注意,也支持optional-optional,但这不是我的问题的一部分.配置可选 - 可选关系时,生成的数据库模式和运行时行为存在明显差异.

Lad*_*nka 13

我不知道为什么在这种情况下允许必需 - 但它不能存在于数据库中,因为关系是在主键上构建的.必需 - 表示如果相关B不存在则不能插入A,如果相关A不存在则不能插入B =>既不能插入A也不能插入B.

数据库关系始终是主体和依赖实体 - 主体可以始终存在而不依赖.

只有当A和B都映射到同一个表(表拆分)时,才能实现EF中所需的实际要求,因为在这种情况下,它们都插入了单个插入命令.


Jul*_*man 5

不是一个真正的答案,但我还有更多的话要说而不是评论.但是你知道,我写了900页的书......这就是我的翻版方式.:)

奇怪的是,我希望流畅的配置行为与数据注释的行为相同,并且我很困惑它没有这样做.(我已经给Rowan Miller写了一个链接到这个帖子以获得他的反馈.)我的意思是:在SaveChanges期间验证约束.

在数据库方面,我和Ladislav一起使用.在模型中,EF使用相关实体的键定义1:1.但是在数据库中,您不能在两个表中都有FK,因此只有数据库中的依赖表才需要它的PK映射到主表中现有PK的约束.

最后,如果你不打算总是处理完整的图表,我理解你不希望EF强制执行这种关系的原因.我认为1:1的关系是EF关系映射中最容易混淆的,我总是发现自己不得不回过头来提醒规则以及事情应该如何运作.