1. 程式人生 > 實用技巧 >Entity Framework Core - 建立並配置模型-生成值的模式 Generated Values

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 的新特性!