当我向 CodeFirst EF6 MVC5 Asp.NET 注册用户时,会导致重复的表



我有这里描述的确切问题:在 MVC4 中注册自定义用户配置文件 ASP.NET 结果会出现重复表

但是该解决方案对我不起作用,因为它适用于 MVC4,而我使用 MVC5。

问题是当我尝试注册一个新用户时,将数据库中几乎所有表复制为复数名称,例如: 图片(复制到(图片

编辑:

我有一个来自 IdentityUser 的扩展类,名为 ApplicationUser,用于在此模型中放置其他属性,例如邮政编码的 id、照片和名称:

public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
        public string Name { get; set; }
        public string Photo { get; set; }
        public int PostalCodeID { get; set; }
        [ForeignKey("PostalCodeID")]
        public virtual PostalCode PostalCode { get; set; }
        public virtual ICollection<Auction> Auctions { get; set; }
        public virtual ICollection<Bid> Bids { get; set; }
        public virtual ICollection<Message> Messages { get; set; }
        public virtual ICollection<Friend> Friends { get; set; }
        public virtual ICollection<BlockHistory> Blocks { get; set; }
    }
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser> {
        public DbSet<PostalCode> PostalCode { get; set; }
        public ApplicationDbContext()
            // ConnectionString
            : base("AuctionsContext", throwIfV1Schema: false)
        {
        }
        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }
}

邮政编码 ID 是表/模型"邮政编码"的外键。一个用户可以有一个邮政编码,但一个邮政编码可以有零个或多个用户。

这是模型"邮政编码":

public class PostalCode {
    public int ID { get; set; }
    [RegularExpression(@"d{4}-d{3}", ErrorMessageResourceType=typeof(Resources), ErrorMessageResourceName="PostalCodeFormat")]
    [Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "Required")]
    [StringLength(8, ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "Length")]
    [Display(Name = "Name_PostalCode", ResourceType = typeof(Resources))]
    public string ZipCode { get; set; }
    public int LocalityID { get; set; }
    public virtual Locality Locality { get; set; }
}

我启用了迁移,但不是在自动模式下,我认为发生这种情况是因为在配置.cs中,我有这段代码

    public Configuration() {
        AutomaticMigrationsEnabled = false;
    }

当我创建第一次迁移并更新数据库时,所有表都已正确创建(名称为单数(,除了 AspNetxxxx 表,这些表是在第一次用户注册发生时自动创建的,也就是大多数表重复时,网络记录器给出了此错误:

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.AspNetUsers_dbo.PostalCodes_PostalCodeID". The conflict occurred in database "PSIProject", table "dbo.PostalCodes", column 'ID'.
The statement has been terminated.
System.Data.SqlClient.SqlException: The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.AspNetUsers_dbo.PostalCodes_PostalCodeID". The conflict occurred in database "PSIProject", table "dbo.PostalCodes", column 'ID'.
The statement has been terminated.

Linha 164:                    PostalCodeID = model.PostalCodeID
Linha 165:                };
Linha 166:                var result = await UserManager.CreateAsync(user, model.Password);
Linha 167:                if (result.Succeeded)
Linha 168:                {

我了解导致此错误的正在发生的事情,在某种程度上,IdentityUser 找不到邮政编码表,因此,它创建了邮政编码表,正是在这个表上,它创建了邮政编码AspNetUsers 之间的关系(我已经检查过了,表 AspNetUsers邮政编码之间没有关系(

附注:我试图将[Table(">PostalCode"(]放在公共类PostalCode之前,但是在注册用户时,我收到一个错误,说dbo。AspNetUsers 是一个无效的对象,所以我验证了数据库,并注意到它没有创建那些自动 AspNetxxxx 表。

你的问题很难理解,但我要在黑暗中疯狂地刺一刀。如果我完全脱离了基础,请随时告诉我并提供其他信息。

默认的实体框架约定是创建表名作为它们所表示的实体的复数版本,因此对于像 Picture 这样的类,您将在数据库中得到一个名为 Pictures 的表,并带有一个s。如果您收到"重复项",我只能推测您正在使用现有数据库或以其他方式手动创建数据库的架构,而不是让实体框架执行此操作。在此手动创建的架构中,您显然以单一方式命名表。我还假设您正在运行自动迁移,否则您只会收到数据库不同步而不是重复任何内容的错误。使用自动迁移时,如果实体框架确定数据库不包含所需的架构,它将相应地自动更新它,在你的方案中,这将导致实体框架查找的约定中命名的"重复"表。

您在这里有两个选择。最好的办法是简单地让公约成为惯例。不要创建自己的架构,也不要根据实体框架约定(复数形式(在架构中命名表。使用 EF6,如果您真的非常关心,您实际上可以更改约定。

选项二是在每个实体类前面加上 Table 属性,以明确告诉实体框架它应该查找什么表名,例如:

[Table("Picture")]
public class Picture
{
    ...
}

但是,这非常麻烦,并且长期使用应用程序容易出错。

最新更新