Entity Framework(代码优先)一对多和一对一关系(有两个实体)。如何?

Entity Framework (Code First) One to Many and One to One relations (with two entities). How to?

我正在尝试使用 EF Code First 执行此操作:

有两个表:Users 和 Areas。一个用户属于一个所需的区域,一个区域可以有零个或一个用户(作为管理员)。那么:

用户 *..1 地区和 用户 0..1 区域

用户class:

public class User {
    public int UserId { get; set; }
    public string Name { get; set; }

    [ForeignKey("Area")]
    public int AreaId { get; set; }
    [InverseProperty("Users")]
    public virtual Area Area { get; set; }

    public virtual Area AreaTitular { get; set; }
}

地区class:

public class Area {
    public int AreaId { get; set; }
    public string Name { get; set; }

    public List<User> Users { get; set; }

    [ForeignKey("User")]
    public int? UserId { get; set; }
    [InverseProperty("AreaTitular")]
    public virtual User User{ get; set; }
}

以及更新数据库命令的错误:

Unable to determine the principal end of an association between the types 'TestEntityFrameworkCodeFirst.Model.Area' and 'TestEntityFrameworkCodeFirst.Model.User'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

任何帮助将不胜感激:)

我不确定这是否可以:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Entity<Area>()
        .HasOptional(i => i.User)
        .WithOptionalDependent();
    base.OnModelCreating(modelBuilder);
}

刚刚在上下文 class 的 OnModelCreating 上添加了这个。这就是它在 SQL 服务器中的样子:

问题出在一对一关系的配置上,因为一端必须是 principal,第二端必须是 dependent.你在配置这种关系的时候,Entity Framework要求依赖的主键也是外键key.So,不要把UsuarioId映射成FK,否则EF要求FK肯定也是PK(评论说属性)。另一个问题是 EF 不知道你们关系中谁是委托人。要指定谁是委托人,请使用 Required 属性。例如,如果您在 AreaTitular 上添加此属性,您指定要创建 UserAreaTitular 属性 必须在保存更改后设置它,因此您的在这种情况下,主体是 Area,依赖项是 User,但这是假设的场景,我不知道你的逻辑。 查看此帖子以获取更多信息:

现在,可以将两端都指定为可选的,但其中之一必须是主要的。如果是这种情况,我建议您评论 Data Annotations 属性并使用 Fluent Api 以这种方式配置关系:

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   {
        modelBuilder.Entity<User>()
            .HasRequired(a => a.Area)
            .WithMany(c => c.Usuarios)
            .HasForeignKey(a => a.AreaId);

        modelBuilder.Entity<Area>()
            .HasOptional(a => a.Usuario)
            .WithOptionalPrincipal(u => u.AreaTitular);
   }

我建议您阅读此 page 以更好地理解一对一关系。