You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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表,最终导致两个上下文各自生成了同名模型的不同表。

具体解决步骤

  1. 限制IdentityDbContext的实体范围
    在IdentityDbContext的OnModelCreating方法中,显式忽略非身份相关的实体,避免EF Core自动映射:

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // 忽略自定义业务实体,仅处理身份相关表
        builder.Ignore<PsychologistProfile>();
        builder.Ignore<WorkSchedule>();
        builder.Ignore<WorkInterval>();
    }
    
  2. 统一表名配置(可选)
    如果需要确保多个上下文对同一实体使用相同表名,可以在模型上添加[Table]特性指定表名,这样即使被多个上下文识别,也会指向同一个表:

    [Table("_PsychologistProfiles")]
    public class PsychologistProfile
    {
        // 模型原有代码...
    }
    
  3. 规范迁移命令
    执行迁移时必须明确指定目标上下文,避免误操作:

    • 迁移业务数据上下文:Add-Migration InitialApplication -Context ApplicationDbContext,随后执行Update-Database -Context ApplicationDbContext
    • 迁移身份上下文:Add-Migration InitialIdentity -Context IdentityDbContext,随后执行Update-Database -Context IdentityDbContext

内容的提问来源于stack exchange,提问作者Vivaldi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 23:35:29