EF Core Generator可空字符串映射问题求助(数据库优先)
问题及解决方案
问题详情
执行查询时抛出异常:
读取属性'EventTracking.EventNotes'的数据库值时出错。预期类型为'System.String',但实际值为null。
场景:采用数据库优先模式,使用Entity Framework Core Generator生成.NET实体类,数据库中EventNotes为可空VARCHAR字段,但生成的C#类将其定义为非可空string,导致null值映射失败。
尝试过两种临时方案,但存在弊端:
- 手动将
string改为string?:生成器重新生成代码时会覆盖修改 - 查询时追加
DefaultIfEmpty():不想在所有查询中重复操作
需求:找到无需手动修改实体类或重复写查询方法的解决方案,要么通过生成器配置自动生成可空字符串类型,要么通过DbContext配置实现null值映射。
相关代码与配置
查询调用代码
return await _context.EventTrackings.FirstOrDefaultAsync();
数据库表定义
CREATE TABLE [dbo].[EventTracking] ( [EventTrackingId] INT NOT NULL IDENTITY (1, 1), [EventTypeId] INT NOT NULL, [DateKey] INT NOT NULL, [EventDate] DATETIME NOT NULL, [EventDurationMinutes] INT NULL, [EventStatus] VARCHAR(255) NULL, [EventNotes] VARCHAR(255) NULL, [CreatedDate] DATETIME NOT NULL DEFAULT GETDATE(), [CreatedByUserId] INT NOT NULL DEFAULT 0, FOREIGN KEY ([CreatedByUserId]) REFERENCES ElkUser([ElkUserId]), FOREIGN KEY ([EventTypeId]) REFERENCES EventType([EventTypeId]), CONSTRAINT [PK_EventTrackingId] PRIMARY KEY CLUSTERED ([EventTrackingId] ASC) WITH (FILLFACTOR = 90) )
生成的实体类
public partial class EventTracking { public EventTracking() { Reservations = new HashSet<Reservation>(); } public int EventTrackingId { get; set; } public int EventTypeId { get; set; } public int DateKey { get; set; } public DateTime EventDate { get; set; } public int? EventDurationMinutes { get; set; } public string EventStatus { get; set; } public string EventNotes { get; set; } public DateTime CreatedDate { get; set; } public int CreatedByUserId { get; set; } public virtual ElkUser CreatedByUserElkUser { get; set; } public virtual EventType EventType { get; set; } public virtual ICollection<Reservation> Reservations { get; set; } }
生成的映射配置
builder.Property(t => t.EventStatus) .HasColumnName("EventStatus") .HasColumnType("varchar(255)") .HasMaxLength(255); builder.Property(t => t.EventNotes) .HasColumnName("EventNotes") .HasColumnType("varchar(255)") .HasMaxLength(255);
使用版本
Microsoft.EntityFrameworkCore- v7.0.15Microsoft.EntityFrameworkCore.SqlServer- v7.0.15- CLI
EntityFrameworkCoreGenerator- 6.0.1
解决方案
方案1:配置Entity Framework Core Generator自动生成可空字符串
在generation.yml文件中开启可空引用类型支持,生成器会自动为数据库中可空的字符串字段生成string?类型:
project: nullableReferenceTypes: true
添加该配置后重新运行生成器,所有可空的VARCHAR/TEXT等字符串字段都会生成可空引用类型,无需手动修改实体类。
方案2:在DbContext中显式配置字段可空性
如果无法修改生成器配置,可扩展实体的映射配置,显式标记字段为非必填,让EF Core正确处理null值:
// 在EventTracking的映射配置类中修改或追加以下代码 builder.Property(t => t.EventNotes) .HasColumnName("EventNotes") .HasColumnType("varchar(255)") .HasMaxLength(255) .IsRequired(false); // 显式设置字段为非必填 // 对EventStatus字段执行同样操作 builder.Property(t => t.EventStatus) .HasColumnName("EventStatus") .HasColumnType("varchar(255)") .HasMaxLength(255) .IsRequired(false);
注意:若映射类是生成器自动生成的部分类,可创建独立的扩展配置类,避免被生成器覆盖。
内容的提问来源于stack exchange,提问作者97WaterPolo
相关产品推荐
相关产品推荐

