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

Docker部署PostgreSQL+.NET应用时,解决'relation "Subjects"不存在'错误

解决"relation 'Subjects' does not exist"错误的方案

1. 修正实体模型的主键与命名错误

(1)给Subject类标记主键

Subject类的id字段未添加[Key]特性,EF Core无法识别其为主键,会导致迁移生成的表结构异常。修改Subject类:

public class Subject
{
    [Key] // 添加主键标记
    public string? id {get;set;} 
    public string? Title {get; set; }
    public int? Credits {get; set; }
    
    public virtual List<SubjectStudent> SubjectStudents {get; set;} // 修正为SubjectStudent(与中间类名一致)

    [ForeignKey("Teacher")]         
    public int? TeacherDni {get; set;}
    public virtual Teacher Teacher {get; set;}          
}

(2)修正Student类的导航属性类型

Student类中Subjects属性的类型是ICollection<SubjectStudents>,但你的中间实体类是SubjectStudent(单数),类型不匹配会导致EF映射错误:

public class Student
{
    [Key]
    public int? Dni {get; set;}
    public string? FirstName { get; set; }
    public string? SurName { get; set; }
    public string? Email {get; set; }
    public string? Password {get; set;}
    public DateTime EnrollmentDate { get; set; }
    public ICollection<SubjectStudent> Subjects { get; set; } // 修正为SubjectStudent
}

(3)修正SubjectStudent类的导航属性与外键配置

中间类的导航属性命名和外键配置存在问题,需明确外键关联:

[PrimaryKey(nameof(SubjectId), nameof(StudentDni))]
public class SubjectStudent
{
    public string? SubjectId {get;set;}
    [ForeignKey(nameof(SubjectId))] // 添加外键标记
    public Subject Subject {get;set;} // 修正为单数Subject,与类名对应
    public int? StudentDni {get;set;}
    [ForeignKey(nameof(StudentDni))] // 添加外键标记
    public virtual Student Student { get; set; } // 修正为单数Student
}

2. 重新生成并应用数据库迁移

(1)本地项目重新生成迁移

打开终端,执行以下命令:

# 生成新的迁移文件
dotnet ef migrations add FixEntityModels
# 将迁移应用到数据库
dotnet ef database update

(2)Docker环境下自动执行迁移

若使用Docker部署,需在应用启动时自动执行迁移。在Program.cs中添加代码:

var app = builder.Build();

// 自动应用未执行的迁移
using (var scope = app.Services.CreateScope())
{
    var dbContext = scope.ServiceProvider.GetRequiredService<YourDbContext>();
    dbContext.Database.Migrate();
}

// 后续中间件配置...

3. 适配PostgreSQL表名大小写规则

PostgreSQL默认区分表名大小写,而EF Core默认生成复数形式的表名(如Subjects)。可通过配置统一表名为小写:
在DbContext的OnModelCreating方法中添加:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 所有表名转为小写
    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        entityType.SetTableName(entityType.GetTableName().ToLower());
    }

    // 也可单独指定表名
    modelBuilder.Entity<Subject>().ToTable("subjects");
    modelBuilder.Entity<SubjectStudent>().ToTable("subject_students");
}

4. 验证数据库表是否存在

进入PostgreSQL容器,执行SQL查询确认表是否生成:

-- 列出public schema下的所有表
SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';

若未找到subjects、subject_students等表,需检查迁移日志或容器内的数据库连接字符串是否正确。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:52:04