.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N151216603
出刊日期:2015/12/30
開發工具: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 - 2》的情境,繼續探討Code First Data Annotations的應用。
DatabaseGenerated Attribute
預設當網域類別(Domain Class)的屬性名稱是ID或「類別名稱+ID」(英文大小寫都可以)時,此屬性將對應到資料庫資料表的主鍵欄位(Primary Key),若屬性是數值型別,也會將此欄位設定為自動編號欄位。這等同於在類別屬性上方套用DatabaseGenerated Attribute,設定其DatabaseGeneratedOption值為「Identity」:
public class Opera {
[DatabaseGenerated( DatabaseGeneratedOption.Identity )]
public int OperaID { get; set; }
public string Title { get; set; }
public int? Year { get; set; }
public string Composer { get; set; }
}
DatabaseGeneratedOption可以設定為:
- None:資料庫不產生值。
- Identity:自動編號。
- Computed:資料新增或修改時,此欄位的值由資料庫產生。
若不希望此屬性不要對應用自動編號欄位,則可以設定DatabaseGeneratedOption值為「None」:
public class Opera {
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int OperaID { get; set; }
public string Title { get; set; }
public int? Year { get; set; }
public string Composer { get; set; }
}
這個範例產生的資料表結構描述,請參考下圖所示:
圖 1
OperaID屬性將會對應到資料表的主鍵欄位(Primary Key),但此欄位的「Identity Specification」設定為「false」,請參考下圖所示:
圖 2
DatabaseGeneratedOption.Computed屬性
當領域類別屬性套用DatabaseGeneratedOption.Computed時,則表示未來此屬性對應的資料庫欄位值是由資料庫產生的,要求Entity Framework Code First未來在新增或修改資料庫資料時,不要產生異動此欄位的SQL程式碼。你可以在byte或timestamp欄位設定DatabaseGeneratedOption.Computed值,或搭配Code First Migration,指定資料庫欄位的計算公式。
例如以下範例程式碼,CreateDate屬性的上方套用了DatabaseGeneratedOption屬性,其值設定為「Computed」:
public class Opera {
[DatabaseGenerated( DatabaseGeneratedOption.None )]
public int OperaID { get; set; }
public string Title { get; set; }
public int? Year { get; set; }
public string Composer { get; set; }
[DatabaseGenerated( DatabaseGeneratedOption.Computed )]
public DateTime CreateDate { get; set; }
}
當你使用類似以下的程式碼修改資料時:
OperaContext context = new OperaContext();
var a = context.Operas.First( m => m.OperaID == 100 );
a.Title = "new title";
context.SaveChanges();
產生的SQL如下所示:
exec sp_executesql N'UPDATE [dbo].[Operas]
SET [Title] = @0
WHERE ([OperaID] = @1)
SELECT [CreateDate]
FROM [dbo].[Operas]
WHERE @@ROWCOUNT > 0 AND [OperaID] = @1',N'@0 nvarchar(max) ,@1 int',@0=N'new title',@1=100
這個範例產生的資料表結構描述,請參考下圖所示:
圖 3
Index Attribute
Entity Framework 6.1版新增Index Attribute,可以為類別屬性對應的資料庫欄位建立索引(Index)。你可以為一到多個屬性套用Index Attribute,來產生多個索引欄位。例如以下程式碼範例,設定Year屬性對應的欄位將成為索引欄位:
public class Opera {
public int OperaID { get; set; }
public string Title { get; set; }
[Index]
public int? Year { get; set; }
public string Composer { get; set; }
}
這個範例產生的資料表結構描述,請參考下圖所示,資料表將產生一個名為「IX_Year」的索引:
圖 4
預設索引命為「IX_屬性名稱」,若想要為其命名可以利用Index Attribute指定名稱,以下範例程式碼指定索引名稱為「IX_PublishYear」:
public class Opera {
public int OperaID { get; set; }
public string Title { get; set; }
[Index("IX_PublishYear")]
public int? Year { get; set; }
public string Composer { get; set; }
}
建立多個索引
SQL Server規定索引鍵欄位的型別不可以是ntext、text、image、varchar(max)、nvarchar(max) 和 varbinary(max) ,因此字串型別的屬性要設定[StringLength]來限定資料的長度,才可以為其建立索引,例如以下範例程式碼:
public class Opera {
public int OperaID { get; set; }
public string Title { get; set; }
[Index]
public int? Year { get; set; }
[Index]
[ StringLength( 20 )]
public string Composer { get; set; }
}
這個範例產生的資料表結構描述,請參考下圖所示:
圖 5
唯一索引
若要建立唯一索引,確保其中的值不重複,則可以設定Index Attribute的IsUnique屬性,將其指定為「true」,例如以下程式碼範例:
public class Opera {
public int OperaID { get; set; }
[Index(IsUnique = true )]
[StringLength( 20 )]
public string Title { get; set; }
public int? Year { get; set; }
public string Composer { get; set; }
}
這個範例產生的資料表結構描述,請參考下圖所示:
圖 6