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

C#项目.NET Core5升Core6 EF报错Claim无合适构造函数

根本原因

这个报错是EF Core 6.0的构造函数绑定逻辑变更导致的,和.NET 6本身没有直接关系:

  • EF Core 5.x版本枚举实体构造函数候选时,会自动跳过参数类型不属于当前模型已映射属性类型的构造函数。System.Security.Claims.Claim类存在一个接收BinaryReader类型参数的构造函数,由于BinaryReader从来不会被映射为实体属性,这个构造函数在5.x版本会被直接排除在候选列表外,EF Core会自动匹配其他参数名与Claim类属性(Type/Value等)匹配的构造函数完成绑定,不会抛错。
  • EF Core 6.0调整了构造函数校验逻辑,会将实体类的所有公开构造函数全部纳入候选校验范围,不会提前过滤参数类型不相关的构造。当EF Core扫描到Claim(BinaryReader reader)这个构造时,发现不存在名为reader的映射属性,就会直接抛出构造函数绑定失败的错误,不会继续校验其他可用构造函数。
  • 触发这个问题的前提是EF Core误将System.Security.Claims.Claim识别为需要持久化的实体,绝大多数场景是开发者在自定义用户实体时,错误添加了类型为ICollection<Claim>的导航属性——Identity框架本身持久化用户声明使用的是内置的IdentityUserClaim实体,运行时才会转换为System.Security.Claims.Claim对象用于身份认证,不需要直接映射Claim类到数据库。

解决方案(无需降级EF Core版本)

方案1(推荐,覆盖99%场景)

在你的ApplicationDbContext的OnModelCreating方法中,显式忽略System.Security.Claims.Claim类型,阻止EF Core将其识别为持久化实体:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    
    // 新增这行配置即可解决报错
    builder.Ignore<System.Security.Claims.Claim>();
    
    // 其余原有模型配置代码保持不变
}

如果你的用户实体中确实添加了ICollection<System.Security.Claims.Claim>类型的导航属性,建议将其替换为ICollection<IdentityUserClaim<string>>(如果你自定义了用户声明实体,替换为你自己的UserClaim类型),从根源上避免EF Core误识别非持久化类型。

方案2(仅当你确实需要持久化System.Security.Claims.Claim实体时使用)

如果你的业务场景确实需要直接映射Claim类到数据库,可以显式为该实体指定EF Core使用的构造函数,跳过对BinaryReader参数构造的校验:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    
    var claimEntity = builder.Entity<System.Security.Claims.Claim>().Metadata;
    // 选择业务需要使用的构造函数,示例为使用type、value两个参数的公开构造
    var targetConstructor = typeof(System.Security.Claims.Claim)
        .GetConstructor(new[] { typeof(string), typeof(string) });
    
    claimEntity.SetConstructorBinding(new ConstructorBinding(
        targetConstructor,
        new List<ParameterBinding>
        {
            new PropertyParameterBinding(claimEntity.FindProperty(nameof(Claim.Type))),
            new PropertyParameterBinding(claimEntity.FindProperty(nameof(Claim.Value)))
        }
    ));
}

配置完成后重新生成迁移、运行即可正常使用,不需要降级任何EF Core相关NuGet包。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 07:21:38