【问题标题】:Issue with EF Core 5 HasDefaultValue, ef pushes default value when value is set to the .Net type defaultEF Core 5 HasDefaultValue 的问题,当值设置为 .Net 类型默认值时,ef 推送默认值
【发布时间】:2021-12-14 14:05:50
【问题描述】:

我在使用实体框架核心插入具有默认值列的记录时遇到了一个奇怪的问题。 有没有其他方法可以获得预期的行为,我错过了什么愚蠢的东西吗?

tldr:将 int 属性 = 0 或 bool 设置为 true 会导致使用默认值 新字符串的 string.empty 给出 ORA-01400: cannot insert NULL (这似乎是 oracle 的事情)

场景: 使用迁移添加新列并添加新记录会导致正常行为(插入默认值)

仅添加一条新记录 oldField 提供= OK "ID" : 6, "OLDFIELD" : "ef test 1", "NEWINT" : 5, "NEWSTRING" : "def", "NEWBOOLFALSE" : 0, "NEWBOOLTRUE" : 1

添加与 .Net 默认值不同的值也可以 "ID" : 12, "OLDFIELD" : "ef test all set", "NEWINT" : 42, "NEWSTRING" : "string here", "NEWBOOLFALSE" : 1, "NEWBOOLTRUE" : 1

现在的问题 当您为 int 指定 0 而为 bool 指定 false 时

var test = new TestDef()
        {
            OldField = "ef bad test",
            NewInt = 0,
            NewBoolFalse = false,
            NewBoolTrue = false
        };
_womaDbContext.Add(test);
await _womaDbContext.SaveChangesAsync();

你会得到"ID" : 36, "OLDFIELD" : "ef bad test", "NEWINT" : 5, "NEWSTRING" : "def", "NEWBOOLFALSE" : 0, "NEWBOOLTRUE" : 1

NewString = string.Empty 给出 oracle 异常 ORA-01400: cannot insert NULL(这似乎是 oracle 的事情)

插入查询正常

INSERT INTO WOMA_SCHEMA.TESTDEF
(ID, OLDFIELD, NEWINT, NEWBOOLFALSE, NEWBOOLTRUE)
VALUES("WOMA_SCHEMA"."ISEQ$$_42048".nextval, 'sql empty',0, 0,0);

这使得不进行更新就无法在 NEWBOOLTRUE 中插入假值或在 NEWINT 中插入 0

testclass(DbContext OnModelCreating 调用 TestDef.OnModelCreating(modelBuilder)):

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;

namespace Test.Model
{
    [Table("TESTDEF")]
    public class TestDef
    {
        [Column("ID")]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Column("OLDFIELD")]
        public string OldField { get; set; }

        [Required]
        [Column("NEWINT")]
        public int NewInt { get; set; }

        [Required]
        [Column("NEWSTRING")]
        public string NewString { get; set; }

        [Required]
        [Column("NEWBOOLTRUE")]
        public bool NewBoolTrue { get; set; }

        [Required]
        [Column("NEWBOOLFALSE")]
        public bool NewBoolFalse { get; set; }

        public static void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Default values
            modelBuilder
                .Entity<TestDef>()
                .Property(e => e.NewInt)
                .HasDefaultValue(5);

            modelBuilder
                .Entity<TestDef>()
                .Property(e => e.NewString)
                .HasDefaultValue("def");

            modelBuilder
                .Entity<TestDef>()
                .Property(e => e.NewBoolTrue)
                .HasDefaultValue(true);

            modelBuilder
                .Entity<TestDef>()
                .Property(e => e.NewBoolFalse)
                .HasDefaultValue(false);
        }
    }
}

【问题讨论】:

    标签: c# oracle entity-framework-core


    【解决方案1】:

    这是众所周知的 EF Core 默认值的行为/缺陷,因为具有 CLR 默认值的属性(0 表示数字,false 表示 boolDateTime.Empty 等)不会作为插入命令的一部分发送,因此服务器应用配置的默认值。

    在 EFC 5.0 之前,除了不使用数据库默认值之外,没有其他解决方案。从 EFC 5.0 开始,解决方法是使用可空支持字段,如 Using nullable backing fieldsNullable backing fields for bool propertiesSchema defaults only 文档主题中所述(奇怪地隐藏在 Additional Change Tracking Features 部分的 Working with default values 子部分中)。

    因此我们的想法是为此类属性使用可为空的支持字段,例如

    private int? _newInt;
    [Required]
    [Column("NEWINT")]
    public int NewInt { get => _newInt ?? 0; set => _newInt = value; }
    
    private bool? _newBoolTrue; 
    [Required]
    [Column("NEWBOOLTRUE")]
    public bool NewBoolTrue { get => _newBool ?? true; set => _newBool = value; }
    

    【讨论】:

    • 这似乎有效,tnx 快速回复。
    • @Ivan Stoev 我有一个类似的问题,需要在此处创建具有非映射属性的字段stackoverflow.com/questions/69769984/…你能帮忙吗
    • @user4912134 EF Core 根本不提供验证服务(即使对于映射的属性,并且未映射的属性也会被完全忽略,就像它们不存在一样) - 您必须手动或使用 UI 框架来执行此操作用过。
    • @Iavn Stoev 非常感谢.. 我一直在头疼.. 你能帮我分享一下如何手动完成,我使用的是 ASP.NET 核心
    • @user4912134 我希望我可以。但恐怕我是 EF Core 方面的专家,但对 ASP.Net Core 和类似的经验为零。希望这些标签中的一些人会帮助你。
    猜你喜欢
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 2020-07-01
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多