.NET
Entity Framework Code First
▌背景
How
to implement Code first in Entity framework.
|
▌環境
l Windows 7 pro
l IIS Express 7.5
l Visual Studio 2012
(C#)
l MS Sql Server 2008
R2
l Entity Framework 5
|
▌步驟
l 設定Web.Config的資料庫Connection String
l 建立基底欄位的類別:BaseEntity
l 實作資料表 Customers,Reservations,Rooms及 設定相關屬性(Pkey, Foreign Key …)
l 建立繼承DbContext的資料庫Context : HotelDbContext
l 實作第一次建立資料庫之後的Initial Load程式碼
|
▌實作
▋Database connection
l 設定Web.Config的資料庫Connection
String
<connectionStrings>
<add name="HotelDbContext" connectionString="Data Source=localhost; Initial Catalog=RoomReserve; Integrated Security=True; MultipleActiveResultSets=True" providerName="System.Data.SqlClient" /> </connectionStrings> |
※以連到本機的Sql Express為例。
※設定的連線名稱:HotelDbContext在步驟2.會使用到。
※設定的連線名稱:HotelDbContext在步驟2.會使用到。
▋Model (DAO)
l BaseEntity
建立基底欄位的類別:BaseEntity 以及設定Property的預設值
public class BaseEntity
{ /// <summary> /// 建立日期 /// </summary> public DateTime CreateOn { get; set; } /// <summary> /// 更新日期 /// </summary> public DateTime UpdateOn { get; set; } public BaseEntity() { CreateOn = DateTime.Now; UpdateOn = DateTime.Now; } } |
l Customer
public class Customer : BaseEntity
{ [Key] [Column(Order = 1)] [Display(Name = "身分字號")] public String RegId { get; set; } [Column(Order = 2)] [Display(Name = "姓名")] public String Name {get; set;} [Column(Order = 3)] [Display(Name = "電話號碼")] public String Phone { get; set; } public virtual ICollection<Reservation> Reservations { get; set; } //備註 } |
※ 備註: 表示一對多關係,一個Customer可以有多筆Reservation。
l Room
public class Room : BaseEntity
{ [Key] [Required] [Column(Order=1)] [Display(Name="房號")] public String RoomId { get; set; } [Column(Order = 2)] [Display(Name = "價格")] public int Price { get; set; } public virtual ICollection<Reservation> Reservations { get; set; } //備註 } |
※ 備註: 表示一對多關係,一個Room可以對應到多筆Reservation。
l Reservation
public class Reservation: BaseEntity
{ [Key] //當欄位型別為int且設定為主索引鍵,則EF會將其自動編號(流水號) [Column(Order = 1)] public int Id { get; set; } [Column(Order = 2)] [Display(Name = "房號")] public String RoomId { get; set; } [Column(Order = 3)] [Display(Name = "身分字號")] public String RegId { get; set; } [Column(Order = 4)] [Display(Name = "人數")] public int People { get; set; } [Column(Order = 5)] [Display(Name = "訂房時間")] public DateTime ReservationOn { get; set; } [Column(Order = 6)] [Display(Name = "入住時間")] public DateTime CheckInOn { get; set; } //備註一 [ForeignKey("RoomId")] public virtual Room Room { get; set; } //備註二 [ForeignKey("RegId")] public virtual Customer Customer { get; set; } } |
※ 備註一:指定RoomId為Foreign Key,且Reference到 Room對應的表格。
※ 備註二:指定RegId為Foreign Key,且Reference到 Customer對應的表格。
※ 備註二:指定RegId為Foreign Key,且Reference到 Customer對應的表格。
▋DbContext
l 建立繼承DbContext的資料庫Context : HotelDbContext
public class HotelDbContext : DbContext
{
public HotelDbContext()
: base("name=HotelDbContext") //指定對應的Connection String名稱 { } //宣告資料模型: Customers (由Customer類別組成) public DbSet<Customer> Customers { get; set; }
//宣告資料模型: Reservations (由Reservation類別組成)
public DbSet<Reservation> Reservations { get; set; } //宣告資料模型: Rooms (由Room物件組成) public DbSet<Room> Rooms { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { try { ///設定Customer 一對多 Reservations modelBuilder.Entity<Customer>().HasMany(
m => m.Reservations).WithRequired(m
=> m.Customer);
///設定Room 一對多 Reservations modelBuilder.Entity<Room>().HasMany(
m => m.Reservations).WithRequired(m
=> m.Room);
} catch (Exception ex) { } }
}
|
l Initial
Load
public class HotelDbInitial :
CreateDatabaseIfNotExists<HotelDbContext> { protected override void Seed(HotelDbContext context) { try { context.Rooms.Add(new Room() { RoomId = "100", Price = 10000 }); context.Rooms.Add(new Room() { RoomId = "101", Price = 9999 }); context.Rooms.Add(new Room() { RoomId = "102", Price = 9998 }); context.Customers.Add(new Customer() { RegId="R22222222", Name = "JB", Phone = "09331111111" }); context.Customers.Add(new Customer() { RegId="A22222222", Name = "Lily", Phone = "0911111111" }); context.SaveChanges(); } catch (Exception ex) { } } } |
然後在Global.asax 裡面的 Application_Start() 加入以下程式碼,即可在建立資料庫後做Initial
Load 。
protected void Application_Start()
{ //… //註冊資料庫Initial Database.SetInitializer(new HotelDbInitial()); } |
▋備註
l 手動指定Table Name
如果我們要手動指定,只要在Model
加上以下attribute
…
[Table("MyRoom")]
public class Room : BaseEntity { … } |
資料庫裡面的表格名稱就會建立成 MyRoom。
建議同時一起修改資料庫Contex裡面的資料模型名稱:
建議同時一起修改資料庫Contex裡面的資料模型名稱:
//宣告資料模型: MyRoom (由Room物件組成)
public DbSet<Room> MyRoom { get; set; } |
這樣在程式裡面操作資料模型時,才不會因為名稱和資料庫表格名稱不同,而造成混淆。
l 宣告Property 在資料庫中為Identity欄位
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
|
如果是Int (int , Int32 …)欄位且指定為Primary key,則EF會自動將其設置為Identity。
l 指定Model欄位在資料庫的型態
[Required]
[Column(TypeName = "NVARCHAR")]
[MaxLength(100)]
public String Name { get; set; }
|
l EF
Code First中定義資料模型的欄位常用Attribute
▌延伸閱讀
沒有留言:
張貼留言