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

EF Core+PostgreSQL遇System.InvalidCastException:modifiedbyuserid列为空

解决EF Core操作PostgreSQL时的System.InvalidCastException(列值null但模型已设为可空)

问题根源

这个错误的核心原因是EF Core与PostgreSQL的列名映射不匹配,导致EF错误地将已定义为可空的属性按非可空类型处理。具体来说:

  • PostgreSQL默认会把未加双引号的列名转为小写存储(比如建表时的ModifiedByUserID实际存储为modifiedbyuserid)
  • EF Core的Npgsql提供器默认遵循「C# PascalCase属性映射到PostgreSQL snake_case列」的规则,但你的模型属性命名(如Modifiedbyuserid)不符合标准PascalCase,同时数据库列名也不是snake_case格式,最终导致映射错位,EF尝试用非可空的读取逻辑处理null值。

解决方案

方案1:显式配置实体与数据库列的映射

在DbContext的OnModelCreating方法中,手动指定每个属性对应的数据库列名,确保完全匹配:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>(entity =>
    {
        entity.ToTable("Users");
        
        entity.Property(e => e.Userid)
            .HasColumnName("UserID");
        
        entity.Property(e => e.Username)
            .HasColumnName("Username");
            
        entity.Property(e => e.Firstname)
            .HasColumnName("FirstName");
            
        entity.Property(e => e.Lastname)
            .HasColumnName("LastName");
            
        entity.Property(e => e.Createdate)
            .HasColumnName("CreateDate");
            
        entity.Property(e => e.Modifieddate)
            .HasColumnName("ModifiedDate");
            
        entity.Property(e => e.Disabled)
            .HasColumnName("Disabled");
            
        entity.Property(e => e.Createdbyuserid)
            .HasColumnName("CreatedByUserID");
            
        entity.Property(e => e.Modifiedbyuserid)
            .HasColumnName("ModifiedByUserID");
    });
}

方案2:修正模型命名规范并匹配数据库最佳实践

把模型属性改成符合C#规范的PascalCase,同时将数据库列名调整为PostgreSQL推荐的snake_case格式,这样EF默认映射规则就能自动匹配:

修正后的C#模型:

public partial class User
{
    public User()
    {
    }

    public long UserId { get; set; }
    public string Username { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime ModifiedDate { get; set; }
    public bool Disabled { get; set; }
    public long? CreatedByUserId { get; set; }
    public long? ModifiedByUserId { get; set; }
}

调整后的数据库表结构(推荐):

CREATE TABLE Users
(
    user_id BIGSERIAL PRIMARY KEY,
    username VARCHAR(255) NOT NULL,
    first_name VARCHAR(255) NOT NULL,
    last_name VARCHAR(255) NOT NULL,
    create_date TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),
    modified_date TIMESTAMP NOT NULL DEFAULT (NOW() AT TIME ZONE 'UTC'),
    disabled BOOL NOT NULL DEFAULT False,
    created_by_user_id BIGINT,
    modified_by_user_id BIGINT
);

方案3:统一EF Core与Npgsql包版本

你的项目中EF Core版本为6.0.8,但Npgsql相关包是6.0.6,版本不一致可能引发兼容性问题。将Npgsql和Npgsql.EntityFrameworkCore.PostgreSQL的版本升级到6.0.8,与EF Core版本保持一致:

<PackageReference Include="Npgsql" Version="6.0.8" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.8" />

验证步骤

  1. 应用上述任一方案后,清理并重新生成项目
  2. 若修改了表结构,执行数据库迁移
  3. 重新运行查询代码,确认错误消失

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:15:44