使用EF访问PostgreSQL时提示relation 'question'不存在的问题排查
问题场景
我有一个位于public模式下的PostgreSQL数据库及数据表,正在使用Entity Framework访问,数据表名为question。此前项目均使用SQL Server,首次搭配PostgreSQL+EF。
相关代码
Question模型类
[Table("question")] public class Question { [Column("id")] public int Id { get; set; } [Column("text")] public string Text { get; set; } public ICollection<Option> Options { get; set; } }
OnModelCreating配置
最初配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Question>() .ToTable("question") .HasMany(q => q.Options) .WithOne(o => o.Question) .HasForeignKey(o => o.QuestionId) .OnDelete(DeleteBehavior.Cascade); }
补充Option配置(编辑1):
modelBuilder.Entity<Question>() .ToTable("question") .HasMany(q => q.Options) .WithOne(o => o.Question) .HasForeignKey(o => o.QuestionId) .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity<Option>() .ToTable("option") .HasOne(o => o.NextQuestion) .WithMany() .HasForeignKey(o => o.NextQuestionId) .OnDelete(DeleteBehavior.Restrict);
简化配置(编辑2,仍报错):
modelBuilder.Entity<Question>() .ToTable("question");
查询代码
var qs = await _context.Questions.ToListAsync();
报错信息
Npgsql.PostgresException (0x80004005): 42P01: relation "question" does not exist
已通过.ToTable()指定表名大小写,排除该因素。
排查方向
显式指定数据库模式:PostgreSQL默认使用
public模式,但EF可能未自动关联,需在配置中明确指定:modelBuilder.Entity<Question>().ToTable("question", "public");或在上下文配置中全局设置默认模式:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseNpgsql("你的连接字符串", o => o.MigrationsHistoryTable("__EFMigrationsHistory", "public")); }检查连接字符串的搜索路径:在连接字符串中添加
Search Path=public参数,确保EF能定位到public模式下的表,示例:Host=localhost;Database=你的库名;Username=postgres;Password=密码;Search Path=public验证表的实际存在性:用pgAdmin或psql执行以下SQL,确认
public模式下确实存在question表:SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'question';若查询无结果,说明表未创建或创建在其他模式下。
查看EF生成的SQL语句:开启EF日志功能,检查实际生成的SQL是否正确引用了
public.question,示例配置:optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information);若生成的SQL为
SELECT * FROM "question",而数据库中表是未加引号创建的(PostgreSQL自动转小写),理论上可匹配;但如果表创建时加了双引号(如CREATE TABLE "Question"),则会出现大小写不匹配,需统一表名或调整EF配置。
内容的提问来源于stack exchange,提问作者maX

