產生的值
資料庫資料行可以透過各種方式產生其值:主鍵資料行經常是自動遞增整數、其他資料行具有預設或計算值等等。此頁面詳細說明使用 EF Core 產生組態值的各種模式。
預設值
在關係資料庫上,可以使用預設值來設定資料行;如果插入資料列時沒有該資料行的值,則會使用預設值。
您可以在屬性上設定預設值:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Rating)
.HasDefaultValue(3);
}
您也可以指定用來計算預設值的 SQL 片段:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Created)
.HasDefaultValueSql("getdate()");
}
計算資料行
在大部分關係資料庫上,資料行可以設定為在資料庫中計算其值,通常是參考其他資料行的運算式:
modelBuilder.Entity<Person>()
.Property(p => p.DisplayName)
.HasComputedColumnSql("[LastName] + ', ' + [FirstName]");
上述會 建立虛擬 計算資料行,其值會在每次從資料庫擷取時計算。 您也可以指定儲存計算資料行 (有時稱為 持續性 ),這表示它會在資料列的每個更新上計算,並且會與一般資料行一起儲存在磁片上:
modelBuilder.Entity<Person>()
.Property(p => p.NameLength)
.HasComputedColumnSql("LEN([LastName]) + LEN([FirstName])", stored: true);
主索引鍵
根據慣例,如果應用程式未提供值,則類型為 short、int、long 或 Guid 的非複合主鍵會設定為為插入實體產生值。 您的資料庫提供者通常會負責必要的設定;例如,SQL Server 中的數值主鍵會自動設定為 IDENTITY 資料行。
如需詳細資訊, 請參閱有關特定繼承對應策略 之金鑰 和 指引的檔。
明確設定值產生
我們上面看到 EF Core 會自動為主鍵設定值產生 ,但我們可能會想要對非索引鍵屬性執行相同的動作。 您可以設定任何屬性,使其針對插入的實體產生其值,如下所示:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime Inserted { get; set; }
}
同樣地,屬性可以設定為在新增或更新時產生其值:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime LastUpdated { get; set; }
}
不同于預設值或計算資料行,我們不會指定 如何產生值;這取決於所使用的資料庫提供者。 資料庫提供者可能會自動設定某些屬性類型的值產生,但其他提供者可能會要求您手動設定如何產生值。
例如,在 SQL Server 上,當 GUID 屬性設定為主鍵時,提供者會自動使用演算法產生最佳的循序 GUID 值來執行產生用戶端的值。 不過,在 ValueGeneratedOnAdd DateTime 屬性上指定 將不會有任何作用( 請參閱下面的章節以取得 DateTime 值產生 )。
同樣地,在新增或更新時設定為產生的 byte[] 屬性,並以 rowversion 資料類型設定為並行權杖,以便在資料庫中自動產生值。 不過,指定 ValueGeneratedOnAdd 沒有任何作用。
如需支援的特定值產生技術,請參閱提供者的檔。 您可以在這裡 找到 SQL Server 值產生檔。
產生日期/時間值
常見的要求是具有資料庫資料行,其中包含第一次插入資料列的日期/時間(新增時產生的值),或上次更新時(新增或更新時產生的值)。 由於有各種策略可以這麼做,EF Core 提供者通常不會針對日期/時間資料行自動設定值產生 - 您必須自行設定。
建立時間戳記
將日期/時間資料行設定為具有資料列的建立時間戳記,通常是使用適當的 SQL 函式設定預設值。 例如,在 SQL Server 上,您可以使用下列專案:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Created)
.HasDefaultValueSql("getdate()");
}
請務必選取適當的函式,因為可能有數個函式存在(例如 GETDATE()
與 GETUTCDATE()
)。
更新時間戳記
雖然預存計算資料行似乎是管理上次更新時間戳記的好解決方案,但資料庫通常不允許在計算資料行中指定這類 GETDATE()
函式。 或者,您可以設定資料庫觸發程式以達到相同的效果:
CREATE TRIGGER [dbo].[Blogs_UPDATE] ON [dbo].[Blogs]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;
UPDATE B
SET LastUpdated = GETDATE()
FROM dbo.Blogs AS B
INNER JOIN INSERTED AS I
ON B.BlogId = I.BlogId
END
如需建立觸發程式的詳細資訊, 請參閱在移 轉中使用原始 SQL 的檔。
覆寫值產生
雖然屬性已設定為產生值,但在許多情況下,您仍可能會明確指定其值。 這是否實際運作取決於已設定的特定值產生機制:雖然您可以指定明確的值,而不是使用資料行的預設值,但計算資料行無法執行相同的作業。
若要使用明確值覆寫產生值,只要將 屬性設定為不是該屬性類型之 CLR 預設值的任何值( null
針對 string
、 0
、 int
Guid.Empty
、 Guid
等)。
注意
嘗試將明確值插入 SQL Server IDENTITY 預設會失敗; 如需因應措施 ,請參閱這些檔。
若要為已設定為新增或更新時產生的值的屬性提供明確值,您也必須設定 屬性,如下所示:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>().Property(b => b.LastUpdated)
.ValueGeneratedOnAddOrUpdate()
.Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Save);
}
無值產生
除了上述案例等特定案例之外,屬性通常未設定任何值產生;這表示應用程式必須一律提供要儲存至資料庫的值。 此值必須先指派給新實體,才能新增至內容。
不過,在某些情況下,您可能想要停用慣例所設定的值產生。 例如,int 類型的主鍵通常會隱含地設定為 value-generated-on-add(例如 SQL Server 上的識別資料行)。 您可以透過下列方式停用此專案:
public class Blog
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int BlogId { get; set; }
public string Url { get; set; }
}