代码优先迁移中的额外外键

本文关键字:迁移 代码 | 更新日期: 2023-09-27 18:27:16

我对实体框架和代码优先迁移有点陌生,所以我希望这是一个容易回答的问题。我正在尝试在ApplicationUser(来自ASP.NET标识)和Member之间创建一对一关系。我有一个会员类:

public class Member
{
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public virtual Address Address { get; set; }
    public UserStatus Status { get; set; }
    public DateTime CreateDate { get; set; }
    public virtual string ApplicationUserID { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; } 
}

和ApplicationUserClass:

public class ApplicationUser : IdentityUser
    {
        public ApplicationUser()
        {
        }       
        public virtual Member Member { get; set; }
    }

在我的DBContext(继承IdentityDbContext)中,我有以下配置:

    modelBuilder.Entity<ApplicationUser>()
            .HasOptional(t => t.Member).WithOptionalPrincipal();
    base.OnModelCreating(modelBuilder);

当我运行代码第一次迁移时,我得到的是:

 CreateTable(
            "dbo.Members",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    FirstName = c.String(),
                    LastName = c.String(),
                    Status = c.Int(nullable: false),
                    CreateDate = c.DateTime(nullable: false),
                    ApplicationUserID = c.String(maxLength: 128),
                    Address_ID = c.Int(),
                    ApplicationUser_Id = c.String(maxLength: 128),
                })
            .PrimaryKey(t => t.ID)
            .ForeignKey("dbo.Addresses", t => t.Address_ID)
            .ForeignKey("dbo.AspNetUsers", t => t.ApplicationUser_Id)
            .ForeignKey("dbo.AspNetUsers", t => t.ApplicationUserID)
            .Index(t => t.ApplicationUserID)
            .Index(t => t.Address_ID)
            .Index(t => t.ApplicationUser_Id);

请注意,我有两个外键,ApplicationUserIDApplicationUser_Id。我想尝试使用FluentAPI(即不是数据注释)来完成所有工作。我该如何配置它,使EF使用ApplicationUserID,即我在类中的字符串ID?我认为Class+ID是惯例,那么为什么要创建另一个外键呢?

代码优先迁移中的额外外键

我认为您应该以这种方式更新您的配置:

modelBuilder.Entity<Member>()
            .HasOptional(x => x.ApplicationUser)
            .WithMany()
            .HasForeignKey(x => x.ApplicationUserID);

这就是EntityFramework处理一对一关系的方式,您必须以这种方式映射它,并在DB表上引入UNIQUE约束。

有关此案例的更多信息,请点击此处:http://weblogs.asp.net/manavi/associations-in-ef-code-first-ctp5-part-3-one-to-one-foreign-key-associations

这是链接中的报价:

原因很简单:Code First(以及EF)不是原生的支持一对一的外键关联。事实上,EF没有支持任何涉及唯一约束的关联场景全部的幸运的是,在这种情况下,我们不在乎目标方是什么的关联,因此我们可以将其视为一对一关联没有许多部分。我们只想表达"这个实体(用户)具有引用另一个实体实例的属性(地址)",并使用外键字段来表示这种关系。基本上EF仍然认为这种关系是多对一的。这是当前EF限制的一种变通方法,它有两个结果:首先,EF不会给我们带来任何额外的约束为了将这种关系强制为一对一关系,我们需要手动我们自己创造。这种缺乏支持的第二个限制强加给我们更重要:一对一的外国关键协会不能是双向的(即,我们不能在地址类)。