2014年8月7日 星期四

[Entity Framework 6] Code Frist (2) - 來自資料庫的Code First

Entity Framework Code First


1.  加入 Entity framework 到專案。
2.  使用 Entity Data Model Wizard 設定一組連線字串
    i.   如果已有現成資料庫,請先加入到伺服器總管。



  ii.   加入ADO.NET實體資料模型」



iii.   選擇「來自資料庫的Code First (已有資料庫)
或選擇「空的Code First模型」稍後設定連線字串。






直接選擇完成。


Wizard
自動建立一個繼承DbContextContext class


連線字串也自動加入到Config:
<connectionStrings>
<
add name="Cht" connectionString="data source=.;initial catalog=Cht;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</
connectionStrings>

3.  加入Model (Entity)

public class ChtAlarmEvent
{
    [
Key]
    [
Required]
    [
MaxLength(32)]
    [
Column(TypeName = "VARCHAR")]
   
public String UUID { get; set; }

   [Required]
   [
MaxLength(8)]
   [
Column(TypeName = "VARCHAR")]
  
public String EventDate { get; set; }

[MaxLength(14)]
[
Column(TypeName = "VARCHAR")]
public String EventDateTime {get;set;}

[
MaxLength(20)]
[
Column(TypeName = "VARCHAR")]
public String Severity {get;set;}

[
MaxLength(1)]
[
Column(TypeName = "VARCHAR")]
public String AlarmSts {get;set;}
}

屬性說明

Attribute
Description
Key
Primary key
Required
NOT NULL
MaxLength
長度限制
Column(TypeName = "")
設定DB對應欄位屬定


4.  修改Context

public class ChtContext : DbContext
{
public ChtContext(): base("Cht")
{}

public DbSet<ChtAlarmEvent> ChtAlarmEvents { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}

5.  Initial load (設定初始化資料)

    i.   新增一個繼承System.Data.Entity.DropCreateDatabaseIfModelChanges<ChtContext>initialize類別,並override Seed 方法

DropCreateDatabaseIfModelChanges請參考MSDN說明

public class ChtInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<ChtContext>
{
protected override void Seed(ChtContext context)
{
var events = new List<ChtAlarmEvent>{
new ChtAlarmEvent(){
EventDate="20140805",
EventDateTime="20140805185122",
UUID="OIU234ADR234FDSF",
Severity=Severity.Critical.ToString()
                }
//other records
};

events.ForEach(e => context.ChtAlarmEvents.Add(e));
context.SaveChanges();
}
}

   ii.       設定專案Config

<entityFramework>
<contexts>
<context type="MonitorEventManager.DAL.ChtContext, MonitorEventManager">
<databaseInitializer type=
"MonitorEventManager.DAL.ChtInitializer, MonitorEventManager" />
           </context>
</contexts>

在這邊指定對應的ContextInitializer,注意必須加上Namespace

6.  設定完以上之後,原本以為可以在資料庫建立我們Model對應的table了,但是實際上並非如此。 設定在Config<databaseInitializer>並不會在程式開始執行的時候就去執行裡面的Initial load程式碼,因為沒有Access db,所以當然也不會建立table

實際上程式必須在Access db的時候,才會去check 是否存在這個model對應的資料表-> Drop and Create-> Intial

例如必須在主程式加入處理資料的程式碼(如下第一張圖)
在執行第一個停駐點後才會執行Drop and CreateIntial(結果如第二張圖)
至於執行完第二個停駐點會塞入第二筆資料。




7.  如果要避免在主程式才建立table,可取消設定Config<databaseInitializer>
改在程式一啟動時(Application_Start or Form_Load…)自行呼叫intializer

Database.SetInitializer(new ChtInitializer());
chtContext.Database.Initialize(true);



8.  Reference


沒有留言:

張貼留言