.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N151216602
出刊日期:2015/12/16
開發工具:Visual Studio 2015 Enterprise
資料庫:SQL Server Express 2014
版本:.NET Framework 4.6、Entity Framework 6.1.3
本系列文章分為三篇,主要介紹使用Entity Framework Code First Data Annotations(資料註解)來客製化資料庫結構描述資訊。本文將延續第一篇文章《Code First Data Annotations - 1》的情境,繼續探討Code First Data Annotations的應用。
ConcurrencyCheck Attribute
ConcurrencyCheck Attribute可以設定在類別的屬性上,用來指明此屬性對應的資料表欄位,將用於多人同時更新、或修改資料庫資料時,資料衝突的檢查動作。你可以在任何型別的屬性上方,套用ConcurrencyCheck Attribute;同樣地,你也可以在多個屬性上方套用ConcurrencyCheck Attribute。參考以下範例程式碼,在「Title」屬性套用ConcurrencyCheck Attribute:
public class Opera {
public int OperaID { get; set; }
[ConcurrencyCheck]
public string Title { get; set; }
public int? Year { get; set; }
public string Composer { get; set; }
}
以下程式碼利用上述的Opera模型,在資料表新增兩筆資料,並修改第一筆資料的Title為新值「new title」:
var operas = new List<Opera>{
new Opera {
Title = "Cosi Fan Tutte",
Year = 1790,
Composer = "Mozart"
},
new Opera() {
Title = "Carmen",
Year = 1875,
Composer = "Bizet"
}
};
operas.ForEach( s => context.Operas.Add( s ) );
context.SaveChanges();
var a = operas.Find( m => m.OperaID == 1 );
a.Title = "new title";
context.SaveChanges();
則 Entity Framework會執行以下SQL程式碼,比對Title欄位的原始值來更新資料,若更新資料時找不到原始資料而發生衝突,將觸發例外錯誤:
exec sp_executesql N'UPDATE [dbo].[Operas]
SET [Title] = @0
WHERE (([OperaID] = @1) AND ([Title] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'new title',@1=1,@2=N'Cosi Fan Tutte'
在多個屬性套用ConcurrencyCheck Attribute
你可以在類別的多個屬性上套用ConcurrencyCheck Attribute,若修改Opera類別程式碼,分別在Title與Composer屬性上套用ConcurrencyCheck Attribute:
public class Opera {
public int OperaID { get; set; }
[ConcurrencyCheck]
public string Title { get; set; }
public int? Year { get; set; }
[ConcurrencyCheck]
public string Composer { get; set; }
}
則Entity Framework會執行以下SQL程式碼比對Title與Composer欄位的原始值來更新資料,
exec sp_executesql N'UPDATE [dbo].[Operas]
SET [Title] = @0
WHERE ((([OperaID] = @1) AND ([Title] = @2)) AND ([Composer] = @3))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ,@3 nvarchar(max) ',@0=N'new title',@1=1,@2=N'Cosi Fan Tutte',@3=N'Mozart'
Table Attribute
Table Attribute用來客製化資料表名稱。預設Entity Framework Code First會根據英文單、複數原則,以類別的名稱來設定資料表名稱。例如當類別是Opera(單數)時,資料表的名稱就會是Operas(複數)。若資料庫資料表的名稱和類別名稱不相同,你可以利用Table Attribute來改寫預設的命名規則,例如以下程式碼範例,將Opera對應的資料表命名為「Opere」:
[Table( "Opere" )]
public class Opera {
public int OperaID { get; set; }
public string Title { get; set; }
public int? Year { get; set; }
public string Composer { get; set; }
}
這個範例產生的資料表結構描述,請參考下圖所示,資料表名稱將會是「Opere」:

設定Schema屬性
使用Table Attribute可以順便設定資料表的Schema屬性,例如以下範例程式碼,指定「Schema為」屬性的值為「North」:
[Table( "Opere" ,Schema ="North")]
public class Opera {
public int OperaID { get; set; }
public string Title { get; set; }
public int? Year { get; set; }
public string Composer { get; set; }
}
這個範例產生的資料表結構描述,請參考下圖所示,資料表的名稱將會是「North.Opere」:

Column Attribute
Column Attribute可以套用在領域類別的屬性上。預設Entity Framework Code First會以類別的屬性名稱,為資料表欄位命名。若資料表欄位名稱和類別屬性名稱不一致,可以使用Column Attribute來設定兩者之間的對應。例如以下程式碼範例,設定「Title」屬性對應的欄位名稱為「Name」;「Composer」屬性對應的欄位名稱為「Author」:
public class Opera {
public int OperaID { get; set; }
[Column("Name")]
public string Title { get; set; }
public int? Year { get; set; }
[Column("Author")]
public string Composer { get; set; }
}
這個範例產生的資料表結構描述,請參考下圖所示:
