ASP.NET Web API迁移PostgreSQL时表重复问题求助
问题描述
首次使用PostgreSQL开发项目,此前一直用SQL Server。目前遇到数据库迁移时表重复的问题:
- 项目中有
PsychologistProfile模型,在ApplicationDbContext里定义为DbSet<PsychologistProfile> _PsychologistProfiles,预期迁移后仅创建_PsychologistProfiles表,但实际还生成了PsychologistProfile表,所有自定义表均存在该情况。 - 项目包含
ApplicationDbContext和IdentityDbContext两个上下文,单独迁移前者时表创建正常,迁移后者后就会生成PsychologistProfile这类额外表。 - 查看数据库约束:
_PsychologistProfiles的外键为FK__PsychologistProfiles_User_UserId,而PsychologistProfile的外键为FK_PsychologistProfile_AspNetUsers_UserId。
相关代码
PsychologistProfile模型
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace PsychoLinkerWebAPI.Models { public class PsychologistProfile { [Key] public string PsychologistId { get; set; } [ForeignKey("User")] public string UserId { get; set; } public string Phone { get; set; } public string AboutMe { get; set; } public string SessionFeedback { get; set; } public string YearsOfExperience { get; set; } public string EducationPlace { get; set; } public string YearOfGraduation { get; set; } public string WorkHours { get; set; } public string BreakDuration { get; set; } public string TimeBeforeBooking { get; set; } public string SessionDuration { get; set; } public string SessionPrice { get; set; } public virtual User User { get; set; } public ICollection<WorkSchedule> WorkSchedules { get; set; } } }
User模型
using Microsoft.AspNetCore.Identity; namespace PsychoLinkerWebAPI.Models { public class User : IdentityUser { public string FirstName { get; set; } public string LastName { get; set; } public DateTime DateOfBirth { get; set; } public string Gender { get; set; } public virtual PsychologistProfile PsychologistProfile { get; set; } } }
ApplicationDbContext
public class ApplicationDbContext : DbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } public DbSet<PsychologistProfile> _PsychologistProfiles { get; set; } public DbSet<WorkSchedule> _WorkSchedules { get; set; } public DbSet<WorkInterval> _WorkIntervals { get; set; } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity<User>() .HasOne(u => u.PsychologistProfile) .WithOne(pp => pp.User) .HasForeignKey<PsychologistProfile>(pp => pp.UserId) .IsRequired(false) .OnDelete(DeleteBehavior.Cascade); } }
解决方案
问题根源
IdentityDbContext会自动包含继承自IdentityUser的User实体,而User模型关联了PsychologistProfile,EF Core会自动识别这个关联关系,并默认以模型名称作为表名创建PsychologistProfile表,最终导致两个上下文各自生成了同名模型的不同表。
具体解决步骤
限制IdentityDbContext的实体范围
在IdentityDbContext的OnModelCreating方法中,显式忽略非身份相关的实体,避免EF Core自动映射:protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // 忽略自定义业务实体,仅处理身份相关表 builder.Ignore<PsychologistProfile>(); builder.Ignore<WorkSchedule>(); builder.Ignore<WorkInterval>(); }统一表名配置(可选)
如果需要确保多个上下文对同一实体使用相同表名,可以在模型上添加[Table]特性指定表名,这样即使被多个上下文识别,也会指向同一个表:[Table("_PsychologistProfiles")] public class PsychologistProfile { // 模型原有代码... }规范迁移命令
执行迁移时必须明确指定目标上下文,避免误操作:- 迁移业务数据上下文:
Add-Migration InitialApplication -Context ApplicationDbContext,随后执行Update-Database -Context ApplicationDbContext - 迁移身份上下文:
Add-Migration InitialIdentity -Context IdentityDbContext,随后执行Update-Database -Context IdentityDbContext
- 迁移业务数据上下文:
内容的提问来源于stack exchange,提问作者Vivaldi
相关产品推荐
相关产品推荐

