EF Core自行生成GUID而非使用Oracle数据库默认值的解决方法
解决Oracle EF Core中让数据库生成主键GUID的问题
问题出在EF Core的默认约定上:当EF Core识别到名为Id的字符串类型主键时,会自动注册一个值生成器来生成带短横线的小写GUID,这个行为会覆盖你通过[DatabaseGenerated(DatabaseGeneratedOption.Identity)]设置的数据库生成规则,导致Oracle的SYS_GUID()默认值无法生效。
你可以通过以下两种方式解决:
方式一:针对单个实体配置(推荐)
在你的DbContext的OnModelCreating方法中,显式配置实体的主键属性,禁用EF Core的自动值生成器,并指定数据库默认值:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Model>(entity => { // 配置主键 entity.HasKey(e => e.Id); entity.Property(e => e.Id) .HasColumnName("COLUMN_NAME") .HasColumnType("VARCHAR2(32)") // 指定数据库默认值为SYS_GUID() .HasDefaultValueSql("SYS_GUID()") // 标记为添加时由数据库生成值 .ValueGeneratedOnAdd() // 禁用EF Core自带的字符串主键值生成器 .Metadata.SetValueGeneratorFactory(null); }); }
同时,确保创建Model实例时不要手动给Id赋值,保持其为null——如果Id已有值,EF Core会认为是用户提供的,不会触发数据库生成逻辑。
方式二:全局配置所有字符串主键
如果你的项目中有多个字符串类型的主键都需要依赖数据库生成默认值,可以在DbContext的ConfigureConventions方法中全局禁用EF Core的自动值生成:
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) { // 对所有字符串类型的主键,禁用EF Core的自动值生成 configurationBuilder.Properties<string>() .When(property => property.IsPrimaryKey()) .DoNotUseValueGenerator(); }
之后,你依然需要为每个实体的主键配置HasDefaultValueSql("SYS_GUID()")(或者确保数据库表已经设置了默认值),这样插入数据时EF Core会留空主键字段,由Oracle通过SYS_GUID()生成32位无短横线的大写GUID。
内容的提问来源于stack exchange,提问作者AlgoRythm
相关产品推荐
相关产品推荐

