簡體   English   中英

EF Core 5 HasDefaultValue 問題,當值設置為 .Net 類型默認值時,ef 推送默認值

[英]Issue with EF Core 5 HasDefaultValue, ef pushes default value when value is set to the .Net type default

我在使用實體框架核心插入帶有默認值列的記錄時遇到了一個奇怪的問題。 有沒有其他方法可以獲得預期的行為,我是否錯過了一些愚蠢的事情?

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

測試類(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);
        }
    }
}

這是 EF Core 默認值的眾所周知的行為/缺陷,因為具有 CLR 默認值的屬性(0 表示數字, false表示boolDateTime.Empty等)不會作為插入命令的一部分發送,因此服務器應用配置的默認值價值。

在 EFC 5.0 之前,除了不使用數據庫默認值之外,沒有其他解決方案。 從 EFC 5.0 開始,解決方法是使用可空支持字段,如使用可空支持字段布爾屬性的可空支持字段僅模式默認值文檔主題(奇怪地隱藏在使用其他更改跟蹤功能部分的默認值小節中)中所述。

所以這個想法是為這些屬性使用可為空的支持字段,例如

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; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM