Entity Framework Core - 建立並配置模型-生成值的模式 Generated Values
值生成的模式
有3個可用於屬性的值生成的模式:
- 無值生成
- 在新增時生成值
- 在新增或更新時生成值
1、無值生成
無值生成意味著您將始終提供要儲存到資料庫中的有效值。必須先將此有效值分配給新實體,然後才能將其新增到上下文中。
2、在新增時生成值
這意味著在新增新實體時生成值。
根據所使用的的資料庫提供程式,值可能是由EF或資料庫中的客戶端生成的。如果值是由資料庫生成的,則在將實體新增到DbContext時,EF可能會分配臨時值。在執行SaveChanges()時,此臨時值將被替換為資料庫生成的值
如果您向上下文新增一個實體,並且該實體已為該屬性分配了一個值,那麼EF將嘗試插入該值,而不是生成新值。如果沒有為屬性賦予一個CLR的預設值(string為null, int為0,Guid為Guid.Empty,等等),則認為該屬性已被賦值。
約定:應用程式不提供值,則將short、int、long、或GUID型別的非複合主鍵設置為“給插入的實體生成值”。資料庫提供程式通常會負責必要的配置,例如,SQL Server 中的數字主鍵將自動設定為標識列。
注意:
如何為新增的實體生成值將取決於所使用的資料庫提供程式。資料庫提供程式可能會自動為某些屬性型別設定值生成,但其他的可能需要您手動設定值生成的方式。
例如,在使用SQL Server時,將自動為GUID屬性生成值(使用SQL Server的GUID順序演算法)。但是,如果在新增的時候指定DateTime屬性,則必須為要生成的值設定一種方法。一種方法是配置GETDATE()的預設值。
可以將任何屬性配置為“給插入的實體生成其值”,資料批註:
[Table("blog",Schema ="ER")] public class BlogModel { public int BlogId { get; set; } public string Url { get; set; } [NotMapped] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime LoadTime { get; set; } public List<PostModel> Posts { get; set; } }
Fluent API:
modelBuilder.Entity<BlogModel>() .Property(b => b.LoadTime) .ValueGeneratedOnAdd();
注意預設值:
在關係資料庫中,可以使用預設值類配置列,如果插入的行沒有沒有該列的值,將使用預設值。在屬性上配置預設值:
modelBuilder.Entity<BlogModel>() .Property(b => b.Url) .HasDefaultValue("www.baidu.com");
還可以指定用於計算預設值的SQL片段:
modelBuilder.Entity<BlogModel>() .Property(b => b.LoadTime) .HasDefaultValue("getdate()");
給屬性指定預設值,會隱式的將屬性配置為“在新增時生成值”模式。
3、在新增或更新時生成值
這意味著每次儲存記錄時(插入或者更新)都會生成一個新值。
與“在新增時生成值”模式一樣,如果您在新新增的實體例項上為屬性指定一個值,那麼將插入該值,而不是正在生成的值。也可以在更新時設定顯式值。
資料批註:
[Table("blog",Schema ="ER")] public class BlogModel { public int BlogId { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public string Url { get; set; } [NotMapped] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime LoadTime { get; set; } public List<PostModel> Posts { get; set; } }
Fluent API:
modelBuilder.Entity<BlogModel>() .Property(b => b.Url) .ValueGeneratedOnAddOrUpdate();
注意計算列:
大多數的關係資料庫上,可以配置計算列。它通常引用其他列:
modelBuilder.Entity<PostModel>() .Property(b => b.ContentCount) .HasComputedColumnSql("LEN(Content)");
支援計算列的建立儲存,是EF Core 5 的新特性!