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

Extra Foreign Key in Code First Migrations

我对 Entity Framework 和 Code First Migration 有点陌生,所以我希望这是一个容易回答的问题。我正在尝试在 ApplicationUser(来自 ASP.NET 身份)和成员之间创建一对一的关系。我有一个会员 class:

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);

注意我有 2 个外键,ApplicationUserIDApplicationUser_Id。我想尝试使用 FluentAPI(即不是数据注释)来做所有事情。我将如何配置它以便 EF 使用 ApplicationUserID,即我在 class 中的字符串 ID?我以为 Class+ID 是惯例,那为什么要创建另一个外键?

我相信你应该这样更新你的配置:

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

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

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

引用自link:

The reason is simple: Code First (and EF in general) does not natively support one-to-one foreign key associations. In fact, EF does not support any association scenario that involves unique constraints at all. Fortunately, in this case we don’t care what’s on the target side of the association, so we can treat it like a to-one association without the many part. All we want is to express “This entity (User) has a property that is a reference to an instance of another entity (Address)” and use a foreign key field to represent that relationship. Basically EF still thinks that the relationship is many-to-one. This is a workaround for the current EF limitation which comes with two consequences: First, EF won't create any additional constraint for us to enforces this relationship as a one to one, we need to manually create it ourselves. The second limitation that this lack of support impose to us is more important: one to one foreign key associations cannot be bidirectional (i.e. we cannot define a User property on the Address class).