EF 新增資料後回傳 IDENTITY 欄位結果

有天跟同事結對開發的時候,發現 EF6 新增後,會多一個 IDENTITY 欄位的查詢,經研究後發現這個是 EF 6 的特性,觀察了一下 EF Core 也有相同的特性

開發環境

  • VS 2019
  • .NET Framework 4.8 / Entity Framework 6.4.4
  • .NET Core 3.1 / Entity Framework Core 3.1.5

說明

這裡我用 Code First 演示,我需要一張 Member 資料表,裡面要有兩個欄位,分別需要以下設定

  • Id 的型別是 Guid,PK,NoClustered。
  • SequenceId 的型別是 long,Enable IDENTITY (自動累加一,一個 Table 只能有一個),Index Clustered。

重點是 IDENTITY 欄位

EF 6 跟 EF Core 實作方式不太一樣,我把他們列出來

 

實作

EF6

POCO 定義

[Table("Member")]
internal class Member
{
    [Key]
    public Guid Id { get; set; }
 
    [Required]
    [StringLength(200)]
    public string Name { get; set; }
 
    public int Age { get; set; }
 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Index("CLIX_Member_SequenceId",IsClustered = true)] 
    public long SequenceId { get; set; }
 
    public string Remark { get; set; }
}

 

DbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Member>()
                .HasKey(r => r.Id,
                        config => config.IsClustered(false) );
 
}

 

完整內容如下
https://github.com/yaochangyu/sample.dotblog/blob/master/ORM/Identity%20Field/EF6/EntityModel/LabDbContext.cs

 

EF Core

POCO 的定義跟 EF 6 一樣

DbContext

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Member>(p =>
                                {
                                    p.HasKey(e => e.Id)
                                     .HasName("PK_Member")
                                     .IsClustered(false);
                                    p.HasIndex(e => e.SequenceId)
                                     .HasName("CLIX_Member_SequenceId")
                                     .IsUnique()
                                     .IsClustered();
                                });
}

 

完整內容如下
https://github.com/yaochangyu/sample.dotblog/blob/master/ORM/Identity%20Field/EFCore3/EntityModel/LabDbContext.cs

 

調用端

新增一筆 Member 資料:

dbContext.Members.Add(toDb);
dbContext.SaveChanges();

觀察 EF 渲染的 SQL 語法,dbContext.Database.Log = Console.WriteLine;
 

代碼如下:

[TestMethod]
public void InsertViaEF6()
{
    var toDb = new Member
    {
        Id   = Guid.NewGuid(),
        Name = "yao",
        Age  = 20
    };
 
    Console.WriteLine($"寫入資料庫之前 {nameof(toDb.SequenceId)} = {toDb.SequenceId}");
 
    using (var dbContext = LabDbContext.Create())
    {
        dbContext.Database.Log = Console.WriteLine;
        dbContext.Members.Add(toDb);
        dbContext.SaveChanges();
    }
 
    Console.WriteLine($"寫入資料庫之後 {nameof(toDb.SequenceId)} = {toDb.SequenceId}");
}

 

toDb.SequenceId .SequenceId 狀態本來是 0,當調用 dbContext.SaveChanges() 之後,就不是 0 了;原來 EF 幫我們渲染出來的語法包含了 SequenceId 的查詢,下圖是 EF 6 的執行結果

 

EF Core 的執行結果如下:

 

 

EF Core 的 Log 注入設定寫在

https://github.com/yaochangyu/sample.dotblog/blob/master/ORM/Identity%20Field/EFCore3/DbOptionsFactory.cs

var loggerFactory = LoggerFactory.Create(builder =>
                                         {
                                             builder
                                                 //.AddFilter("Microsoft", LogLevel.Warning)
                                                 //.AddFilter("System", LogLevel.Warning)
                                                 .AddConsole()
                                                 ;
                                         });

專案位置

https://github.com/yaochangyu/sample.dotblog/tree/master/ORM/Identity%20Field

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2019 .NET

Image result for microsoft+mvp+logo