我會稱之爲錯誤。
我扣合在一起,一個簡單的測試,只是一些默認類:
public class Test
{
public int ID { get; set; }
public int IntDef { get; set; }
public bool BoolDef { get; set; }
public DateTime? DateDef { get; set; }
}
(請注意,日期時間爲空)
映射:
modelBuilder.Entity<Test>().HasKey(a => a.ID);
modelBuilder.Entity<Test>().Property(s => s.DateDef).HasDefaultValueSql("GETDATE()");
modelBuilder.Entity<Test>().Property(s => s.IntDef).HasDefaultValueSql("1");
modelBuilder.Entity<Test>().Property(s => s.BoolDef).HasDefaultValue(true);
// Equivalent:
// modelBuilder.Entity<Test>().Property(s => s.BoolDef).HasDefaultValueSql("1");
SQL語句創建表格:
CREATE TABLE [Tests] (
[ID] int NOT NULL IDENTITY,
[BoolDef] bit NOT NULL DEFAULT 1,
[DateDef] datetime2 DEFAULT (GETDATE()),
[IntDef] int NOT NULL DEFAULT (1),
CONSTRAINT [PK_Tests] PRIMARY KEY ([ID])
);
當我插入一個新的Test
不設置任何值,插入語句是:
INSERT INTO [Tests]
DEFAULT VALUES;
SELECT [ID], [BoolDef], [DateDef], [IntDef]
FROM [Tests]
WHERE @@ROWCOUNT = 1 AND [ID] = scope_identity();
您將看到三個默認值(和生成的標識值)從後插入數據庫中讀取。 [順便說一下,這在EF-Core中是新的。在EF6中,插入(和更新)後僅從數據庫中讀取標記爲DatabaseGeneratedOption.Computed
的標識值和列值]。
這是在創建Test
對象:
ID IntDef BoolDef DateDef
1 1 True 21-11-16 19:52:56
現在我插入一個新的Test
並指定所有值,但是,只是爲了好玩,我使用默認值非空類型:
var item = new Test
{
IntDef = default(int), // 0
BoolDef = default(bool), // false
DateDef = default(DateTime), // 01-01-01 0:00:00
};
這裏的SQL語句:
exec sp_executesql N'SET NOCOUNT ON;
INSERT INTO [Tests] ([DateDef])
VALUES (@p0);
SELECT [ID], [BoolDef], [IntDef]
FROM [Tests]
WHERE @@ROWCOUNT = 1 AND [ID] = scope_identity();
',N'@p0 datetime2(7)',@p0='0001-01-01 00:00:00'
當然,EF無法推斷默認值是故意分配的。因此,如您所見,僅爲可空的DateTime
列插入分配的值,而不是不可空列。現在插入後,不會從數據庫讀取DateDef
的值。
實體值是:
ID IntDef BoolDef DateDef
1 1 True 01-01-01 0:00:00
沒有什麼人會拯救實體--not在所有後想到!
這意味着:
在配置屬性與EF-核心默認值,這個默認值是比淨默認值不同,你不能爲默認值插入一個實體.Net類型(如布爾型的false
)。
我認爲這是一個嚴重的錯誤,可能它甚至會使有關默認值的EF-Core新行爲失去資格。
加成
正如伊萬的評論說,你可以從你設置默認值的加入ValueGeneratedNever()
停止EF,例如:
modelBuilder.Entity<Test>().Property(s => s.IntDef)
.HasDefaultValueSql("1").ValueGeneratedNever();
現在的價值將被保存,因爲它是和EF在插入和更新後將不會讀回它。總而言之,我認爲定義不可爲空的屬性的默認值是沒有用的。
經過EF Core 1.1.0預覽測試。
一般行爲是「列的默認值是插入新行但未爲該列指定值時將插入的值」。 在你的情況看起來你正在失去設置的值。你可以發佈你的代碼嗎? – kumaro
FWIW,EF6不支持默認值 - 即使非'NULL'列具有明確的默認值集,您也必須明確指定所有列的值。 – Dai
在這種情況下,您可以刪除列的配置以禁用默認值行爲,這樣默認值將由數據庫提供。你能顯示你的代碼(DbContext,Mappings,Pocos)嗎? –