我在使用物體框架核心插入帶有默認值列的記錄時遇到了一個奇怪的問題。有沒有其他方法可以獲得預期的行為,我是否錯過了一些愚蠢的事情?
tldr:將 int 屬性 = 0 或 bool 設定為 true 會導致使用默認值 string.empty 新字串給出 ORA-01400:無法插入 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);
}
}
}
uj5u.com熱心網友回復:
這是公知的行為/ EF核心的默認值的缺陷,由于具有CLR默認(0代表數字,特性false為bool,DateTime.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; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/341337.html
