1. 程式人生 > >(19)ASP.NET Core EF建立模型(包含屬性和排除屬性、主鍵、生成的值)

(19)ASP.NET Core EF建立模型(包含屬性和排除屬性、主鍵、生成的值)

1.什麼是Fluent API?

EF中內嵌的約定將POCO類對映到表。但是,有時您無法或不想遵守這些約定,需要將實體對映到約定指示外的其他物件,所以Fluent API和註解都是一種方法,這兩種方法是用來配置EF在對映屬性時繞開約定。Code first fluent API最常訪問通過重寫OnModelCreating方法在派生DbContext。

2.包含屬性和排除屬性

按照約定,資料模型中都包含一個getter和一個setter公共屬性。

2.1包含屬性

包含屬性官網解釋有點難以理解,我個人認為在OnModelCreating方法配置包含Blog模型,那麼當我們呼叫Blog模型讀寫資料時候就會從連線資料庫中讀寫對應Blog表。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  modelBuilder.Entity<Blog>();
}

2.2排除屬性

如果你不想往BlogMetadata上讀寫資料,可以使用資料批註或者fluent API從模型中排除該實體型別。

2.2.1資料批註
namespace EFModeling.DataAnnotations.IgnoreType
{
    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
    }
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
        public BlogMetadata Metadata { get; set; }
}
 //讀寫不對映該實體
    [NotMapped]
    public class BlogMetadata
    {
        public DateTime LoadedFromDatabase { get; set; }
    }
}
2.2.2Fluent API
namespace EFModeling.FluentAPI.IgnoreType
{
    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
             //Ignore方法就是讀寫不對映該實體
        modelBuilder.Ignore<BlogMetadata>();
        }
    }
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
        public BlogMetadata Metadata { get; set; }
    }
    public class BlogMetadata
    {
        public DateTime LoadedFromDatabase { get; set; }
    }
}

3.主鍵

使用關係型資料庫時候,都會涉及到主鍵概念,用作每個實體例項的主要唯一識別符號。

3.1資料批註

namespace EFModeling.DataAnnotations.KeySingle
{
    class MyContext : DbContext
    {
        public DbSet<Car> Cars { get; set; }
    }
    class Car
    {
       //設定LicensePlate為主鍵
        [Key]
        public string LicensePlate { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
    }
}

3.2Fluent API

namespace EFModeling.FluentAPI.KeySingle
{
    class MyContext : DbContext
    {
        public DbSet<Car> Cars { get; set; }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Car>()
          //設定LicensePlate為主鍵
                .HasKey(c => c.LicensePlate);
        }
    }
    class Car
    {
        public string LicensePlate { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
    }
}

4.生成值

有三個可用於屬性的值生成模式:
●無值生成:沒有值生成意味著,需始終提供要儲存到資料庫的有效值。必須先將有效的值賦予新的實體,再將這些新的實體新增到上下文中。
●在新增時生成值:在新增時生成值,意思是為新實體生成值。
●在新增或更新時生成值:在新增或更新時生成值,意味著在每次儲存該記錄(插入或更新)時生成新值。
注:如果想在資料庫端新增或更新時自動生成值,我們可以通過觸發器和配置預設值等方法生成。例如,如果指定在新增或更新時要生成DateTime屬性,則必須設定生成值的方法。若要執行此操作,一種方法是配置GETDATE() 的預設值以生成新行的值,然後即可使用資料庫觸發器在更新過程中生成值,如下面的示例觸發器所示:

USE [Blogging]
GO
/****** Object:  Trigger [dbo].[Blog_Update_Trigger]    Script Date: 2019/10/22 16:18:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[Blog_Update_Trigger] ON [dbo].[Blog]
    AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;         
    IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;
DECLARE @Id INT

    SELECT @Id = INSERTED.BlogId
    FROM INSERTED
          
    UPDATE dbo.Blog
    SET Updatetime = GETDATE()
    WHERE BlogId = @Id
END

4.1資料批註

4.1.1無值生成
public class Blog
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int BlogId { get; set; }
    public string Url { get; set; }
}
4.1.2在新增時生成值
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public DateTime Inserted { get; set; }
}
4.1.3在新增或更新時生成值
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime LastUpdated { get; set; }
}

4.2Fluent API

4.2.1無值生成
modelBuilder.Entity<Blog>()
    .Property(b => b.BlogId)
    .ValueGeneratedNever();
4.2.2在新增時生成值
modelBuilder.Entity<Blog>()
    .Property(b => b.Inserted)
.ValueGeneratedOnAdd();
4.2.3在新增或更新時生成值
modelBuilder.Entity<Blog>()
    .Property(b => b.LastUpdated)
    .ValueGeneratedOnAddOrUpdate();


參考文獻:
包含屬性和排除屬性
主鍵
生成