EF Core 异常:该属性没有设置值,并且没有可用于类型属性的值生成器

Posted

技术标签:

【中文标题】EF Core 异常:该属性没有设置值,并且没有可用于类型属性的值生成器【英文标题】:EF Core Exception: The property does not have a value set and no value generator is available for properties of type 【发布时间】:2022-01-15 06:10:48 【问题描述】:

我正在使用 .net6 和 efcore6。

我有一个名为 Notification 的数据库实体,它的主键类型为 NotificationId。我正在使用类型转换器和值转换器来使 EFCore 能够在复杂类型和基本 CLR 类型之间进行转换。我的复杂类型基于整数。

当我尝试将新记录保存到此数据库时,我收到一个异常,似乎表明我没有配置值生成器。

完整的例外是: “Notification.Id”属性没有设置值,并且“NotificationId”类型的属性没有可用的值生成器。在添加实体之前为属性设置一个值,或者在“OnModelCreating”中为“NotificationId”类型的属性配置一个值生成器

在我的实体类型配置中,我有:

        builder.Property(x => x.Id)
            .ValueGeneratedOnAdd()
            .HasConversion(
                x => x.Value,
                x => IntIdValue.From<TKey>(x))
            ;
        builder.HasKey(x => x.Id);

这正确地将 Id 类型设置为 Identity,以及迁移中显示的主键:

        migrationBuilder.CreateTable(
            name: "Notification",
            columns: table => new
            
                Id = table.Column<int>(type: "int", nullable: false)
                    .Annotation("SqlServer:Identity", "1, 1"),

            ...
            constraints: table =>
            
                table.PrimaryKey("PK_Notification", x => x.Id);

如何说服 EF 使用身份值生成器?

【问题讨论】:

值转换器不会为空值运行。这可能是问题吗? docs.microsoft.com/en-us/ef/core/modeling/… @DavidBrowne-Microsoft 这是一个有趣的想法,但我明白这就是 EF 知道如何处理数据库生成的值的方式。我尝试将“值”设置为 0,但由于多个记录具有相同的“idl”,这会混淆更改检测代码。 【参考方案1】:

这个异常是因为值转换器收到了一个空值。通过确保强类型 id 不为 null 并将以下行添加到属性配置中,我设法获得使用强类型 id 的自动递增整数: .Metadata.SetBeforeSaveBehavior(PropertySaveBehavior.Ignore)

编辑: 这种方法有一个陷阱。

这与更改跟踪有关。从 ef core 3.0 和 this GitHub issue 开始,当您对键使用自动递增且键值不是默认值时,实体将以“已修改”状态而不是“已添加”状态添加。这是当前解决方案的一个问题,因为我们从未为强类型 ID 设置 null。我们必须手动开始跟踪处于“已添加”状态的实体(使用 DbContext Add 方法),其他类型的自动跟踪将不起作用(例如,将实体添加到导航属性集合中以实现一对多关系)。正在通过this GitHub issue 跟踪对此的官方支持。

【讨论】:

以上是关于EF Core 异常:该属性没有设置值,并且没有可用于类型属性的值生成器的主要内容,如果未能解决你的问题,请参考以下文章

要在 EF Core 中添加没有外键的导航属性,使用 .NET Core Web API 进行 DB-first 迁移

什么是 Entity Framework Core 属性等价于 modelBuilder 的 HasDefaultValueSql?

非托管代码中的 ASP Net Core 1.1 和 EF 6 异常?

EF Core 2 如何在 IdentityUser 上包含角色导航属性?

EF Core 如何实现对值对象更改的审计日志

AutoMapper + EF Core:查询嵌套属性等于值的位置