AspNetUsers的ID作为单独表中的外键,一对一的关系

时间:2014-09-17 07:09:48

标签: c# asp.net database entity-framework one-to-one

我上下打量,尝试了将AspNetUser表的外键存储在单独的Customer表中的所有不同和各种方法。我仍然是ASP.NET和实体框架的新手,但我已经阅读了不少帖子和文档。

目前这就是我所拥有的

模型

public class Customer
{
    [Display (Name="Customer ID")]
    public int CustomerID { get; set; }

    public string UserId { get; set; }
    [ForeignKey("UserId")]
    public virtual ApplicationUser ApplicationUser { get; set; }

}


 public class ApplicationUser : IdentityUser
{
    public virtual Customer Customer { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Customer> Customers { get; set; }

    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

}

我收到此错误,引用

  

无法确定类型'TestApplication.Models.Customer'和'TestApplication.Models.ApplicationUser'之间关联的主要结尾。必须使用关系流畅API或数据注释显式配置此关联的主要结尾。

我也试过这个人的方法:The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations

所以我注释掉了ForeignKey注释并使用了人的建议,使用了“modelBuilder”方法。当我更新我的数据库时,AspNetUsers表中的'Id'在Customers表中(这很好),但CustomerID作为ForeignKey也在AspNetUsers表中,这不是我想要的。

我想要的是AspNetUsers的'Id'作为ForeignKey在Customers表中。

2 个答案:

答案 0 :(得分:13)

在一对一关系中,“子”表(在您的情况下为Customer)应与相关表具有相同的主键,即外键。

您提供的代码示例意味着,在Customer中,您将拥有一个名为CustomerID的PK,它与UserId不同。

这适用于您的情况(未经测试):

public class Customer
{
    [Key]
    public string UserId { get; set; }

    [ForeignKey("UserId")]
    public virtual ApplicationUser ApplicationUser { get; set; }
}

public class ApplicationUser : IdentityUser
{
    public virtual Customer Customer { get; set; }
}

修改

MSDN for ForeignKeyAttribute州:

  

如果将ForeigKey属性添加到外键属性,则为   应指定关联导航属性的名称。如果你   您应该将ForeigKey属性添加到导航属性   指定关联外键的名称。

我将此解释为应该可以将ForeignKey属性添加到导航属性或外键属性,并且这两种方式都应该有效,但显然不行。按照以下方式移动它应该可以解决问题。

public class Customer
{
    [Key, ForeignKey("ApplicationUser")]
    public string UserId { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }
}

public class ApplicationUser : IdentityUser
{
    public virtual Customer Customer { get; set; }
}

答案 1 :(得分:5)

我知道这篇文章已有2年历史,但更好的解决方案是使用Fluent API设置外键(而不是在Customer类中使用[ForeignKey]属性。以下是如何操作:

public class Customer
{
    public int CustomerID { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }
}

public class ApplicationUser : IdentityUser
{
    public virtual Customer Customer { get; set; }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext() : base("DefaultConnection")
    {
    }

    public DbSet<Customer> Customers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // one-to-zero or one relationship between ApplicationUser and Customer
        // UserId column in Customers table will be foreign key
        modelBuilder.Entity<ApplicationUser>()
            .HasOptional(m => m.Customer)
            .WithRequired(m => m.ApplicationUser)
            .Map(p => p.MapKey("UserId"));
    }

}

这将在UserId表中创建Customers列,该列是AspNetUsers表的外键。您可以省略.Map(p => p.MayKey("UserId")),EF将按惯例命名外键ApplicationUser_Id