EF从代码问题生成数据库

时间:2013-12-11 12:13:08

标签: c# asp.net sql entity-framework asp.net-mvc-5

让我试着解释一下。

我开始了一个新项目(MVC5),我创建了一个包含2个表(来自EF视频示例)博客和帖子的数据库。 我在数据库中创建了关系,然后从VistualStudioGallery.com下载了EF工具

然后我使用该工具对表进行反向工程以生成上下文和模型类/映射。

到目前为止一切顺利。

然后我修改了db上下文,如下所示:

public partial class EfExampleContext : IdentityDbContext<ApplicationUser>
{
    public EfExampleContext()
        : base("Name=DefaultConnection")
    {
    }

    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new BlogMap());
        modelBuilder.Configurations.Add(new PostMap());
    }
}

然后我删除了数据库并且F5运行了我的项目,希望它能生成我的数据库。 我注意到它生成了帖子博客 AspNetUsers AspNetUserRoles AspNetRoles ,具有正确列和关系的 AspNetUserClaims AspNetUserLogins 表。

然后我删除了数据库和 AspNetUser 模型。 然后我删除了对以下内容的引用:

  1. 的EntityFramework
  2. Microsoft Asp.net Identity Core
  3. Microsoft Asp.net Identity EntityFramework
  4. Microsoft Asp.net Identity Owin
  5. 然后使用最新版本安装它们。我这样做是因为我想使用 IdentityUser 而不是 AspNetUser (存在一些差异)。

    然后我F5运行我的项目来创建我的数据库,这就是问题开始的地方......

    IdentityUser 如下所示:

    public class IdentityUser : IUser
    {
        public IdentityUser();
        public IdentityUser(string userName);
    
        public virtual ICollection<IdentityUserClaim> Claims { get; }
        public virtual string Id { get; set; }
        public virtual ICollection<IdentityUserLogin> Logins { get; }
        public virtual string PasswordHash { get; set; }
        public virtual ICollection<IdentityUserRole> Roles { get; }
        public virtual string SecurityStamp { get; set; }
        public virtual string UserName { get; set; }
    }
    

    请注意ICollection导航属性 IdentityUserLogin 模型如下所示:

    public class IdentityUserLogin
    {
        public IdentityUserLogin();
    
        public virtual string LoginProvider { get; set; }
        public virtual string ProviderKey { get; set; }
        public virtual IdentityUser User { get; set; }
        public virtual string UserId { get; set; }
    }
    

    正如您所看到的,IdentityUser可以有多个登录,而登录有一个用户。如果我运行该项目, IdentityUserLogins 表如下所示:

    CREATE TABLE [dbo].[IdentityUserLogins](
        [UserId] [nvarchar](128) NOT NULL,
        [LoginProvider] [nvarchar](max) NULL,
        [ProviderKey] [nvarchar](max) NULL,
        [User_Id] [nvarchar](128) NULL,
     CONSTRAINT [PK_dbo.IdentityUserLogins] PRIMARY KEY CLUSTERED 
    (
        [UserId] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    

    这里有问题。 UserId是一个PK,所以它不能与 IdentityUsers 建立0到多的关系,这就是为什么EF正在添加其他 User_Id 列,但这没有任何意义。

    我的问题是,有没有人遇到过这个问题? 如果是这样,我如何生成正确的映射来修复它?

    请注意显然我无法更改 IdentityUser 类,以使 ICollection 成为单个引用(即不是集合)

    / r3plica

1 个答案:

答案 0 :(得分:0)

因为公约

public class IdentityUserLogin
{

 public IdentityUserLogin();

public virtual string LoginProvider { get; set; }
public virtual string ProviderKey { get; set; }
public virtual string UserId { get; set; }  // if i am the key to IdentityUser

 [ForeignKey("UserId")] //  IdentityUserId instead of USerId may have worked.
                        //  see http://msdn.microsoft.com/en-us/data/jj713564 and  
                        // http://msdn.microsoft.com/en-us/data/jj591583
public virtual IdentityUser User { get; set; }

}

EDIT2 Fluent API ..根据需要更改为1:1 /!:M / M:M,必需/可选等

 modelBuilder.Entity<IdentityUserLogin>().HasRequired(t=>t.IdentityUser).WithMany().HasForeignKey(t=>t.UserId) 

fluent api