也許有人問,為什麼要用EF創建愛你數據表,code first好處是什麼? 使用EF創建資料庫/表,只需要設計簡單的C#類,再表內容變化的時候他會自動更新資料庫結構,並且保留原有數據。 EF很強大,支持主外鍵並且能生成和db里一樣的數據類型。由於我們這兩個表簡單,關於進階的知識我會放在這篇文章的底部 ...
也許有人問,為什麼要用EF創建愛你數據表,code first好處是什麼?
使用EF創建資料庫/表,只需要設計簡單的C#類,再表內容變化的時候他會自動更新資料庫結構,並且保留原有數據。
EF很強大,支持主外鍵並且能生成和db里一樣的數據類型。由於我們這兩個表簡單,關於進階的知識我會放在這篇文章的底部作為附錄。
根據需求,我們有兩種 input 文件。一種是trend 的一種是bar的 我們先來看看這兩種文件里的數據:
Trend :
id taskid taskname time b1 equal b2 uncertain grandtotal 0 1 task1 2012-6-27 200 300 280 220 1000
Bar :
KeyWord B1Better Equal B2Better Winner 聯眾 2 0 3 0 0 B1 瘋狂倒計時 0 0 3 0 0 B2 張娜拉 0 1 2 2 0 B1 截圖軟體 1 0 1 1 2 B2
我們需要show 2個 chart。
那麼我們設計2個表來存儲 trend chart 和barchart 的數據,名為Trend 和Bar(本來應該是3個表。由於我們是為了自己練習,設計2個就好。)
到這裡,我才發現我們還沒為我們的project 起名字呢。叫什麼好呢?我們就叫 ReportingSyncer吧。
Reporting(報表),sync(同步),為什麼加er?現在的project 命名的時候往往都擬人化,顯得生動外加比較給力。
【開始動手】
打開vs 2010創建一個新的class library 命名為ReportingDBManager。刪除自動生成的class1.cs 。
修改sln(解決方案的名稱為ReportingSyncer)。
修改命名空間:右鍵點擊ReportingDBManager。properties(屬性)->Application:CnBlogsDemos.ReportingDBManager。為啥要改?因為引用起來方便一點,而且也顯得專業:)
現在你的sln應該是這樣
添加Entity Framework 引用,得到這個dll 有兩種方法:
使用NuGet ,或者去下載一個dll。在這裡我使用Nuget ,EF最新版是4.3.1
【創建表的映射類】
添加完引用之後,我們就開始創建我們的表類了。
添加兩個class ,名為 Trend 和 Bar。
對應上邊input 文件的類型,我們設計兩張 匹配的表。
bar.cs:
namespace CnBlogsDemos.ReportingDBManager { using System.ComponentModel; using System.ComponentModel.DataAnnotations; public class Bar { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] //主鍵 自增 public int ID { get; set; } public int TaskID { get; set; } [MaxLength(200)] public string TaskName { get; set; } /*有朋友要問了,導入文件里明明沒有以上兩個欄位,為什麼要設定他們? 因為導入的時候是根據每個task 導入的,我們會在commandline里數據task id 和task name 這樣才可以讓兩個表聯繫起來,後期好做報表的drill down (鑽入) */ [MaxLength(500)] public string KeyWord { get; set; } public int B1Better { get; set; } public int Equal { get; set; } public int B2Better { get; set; } [MaxLength(50)] public string Winner { get; set; } public string type { get; set; } [DefaultValue(true)] public bool IsActive { get; set; } } }
trend.cs
namespace CnBlogsDemos.ReportingDBManager { using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; public class Trend { public int id { get; set; } public int TaskID { get; set; } public string TaskName { get; set; } public DateTime Time { get; set; } public int B1Better { get; set; } public int Equal { get; set; } public int B2Better { get; set; } public int UnCertain { get; set; } public int GrandTotal { get; set; } [MaxLength(50)] public string type { get; set; } [DefaultValue(true)] public bool IsActive { get; set; } } }
兩個表類創建好了。如何和資料庫聯繫到一塊呢?我們需要使用EF創建一個dbcontext類了。
添加新類:DbStoreContext.cs
namespace CnBlogsDemos.ReportingDBManager { using System.Data.Entity; using System.Data.Entity.Migrations; internal sealed class ReportingDbMigrationsConfiguration : DbMigrationsConfiguration<DbStoreContext> { public ReportingDbMigrationsConfiguration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; } } public class DbStoreContext : DbContext { public DbStoreContext() : base("name=ReportingDataBase") { Database.SetInitializer<DbStoreContext>( new MigrateDatabaseToLatestVersion<DbStoreContext, ReportingDbMigrationsConfiguration>()); this.Configuration.LazyLoadingEnabled = false; } public DbSet<Bar> Bars { get; set; } public DbSet<Trend> Trends { get; set; } } }
上邊的兩個Dbset 就是我們要創建的兩個表。
檢查項目中app.config文件,我們會看到:
<entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"> <parameters> <parameter value="Data Source=.\SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True" /> </parameters> </defaultConnectionFactory> </entityFramework>
EF預設指定的資料庫是本地的Express。我們可以更改成其他標準資料庫或者是遠程資料庫(當然,你要有許可權哦)。
我們想在另一個project 里指定資料庫連接。先把這個appconfig刪除。
有朋友要問了,什麼時候能生成DB,table啊?我怎麼看不見?
別急,在我們第一次調用這個dbcontext 類的時候就會創建/更新啦!
我會在下一章做講解。
【附錄】
EF創建table 時候的一些技巧,查了好多資料,希望能幫助大家:
主鍵:
[Key] public int EngineID { get; set; }
自增主鍵:
[Key,DatabaseGenerated(DatabaseGeneratedOption.None)] public int EngineID { get; set; }
可以編輯的主鍵(預設是readonly)
[Key,Editable(true),DatabaseGenerated(DatabaseGeneratedOption.None)] public int EngineID { get; set; }
非空欄位:
[Required] public string EngineName { get; set; }
限定長度的非空欄位:
[Required, MaxLength(256)] public string EngineName { get; set; }
外鍵比較特殊,需要解釋一下兩個table之間的關係。
table1包含 一個 欄位 taskID。
table task 的主鍵是taskID。需要創建愛你一個 task類型的欄位。關係如下:
public class Table1 { [Required, ForeignKey("Task")] public int TaskID { get; set; } public virtual Task Task { get; set; } } public class Task { [Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int TaskID { get; set; } }
時間戳:
[ConcurrencyCheck] [Timestamp] public byte[] TimeStamp { get; set; }
c# 里的 int32 對應 db 里的int 。int16 對應 smallint,bool 對應bit,byte[]對應binary等等。
參考頁面:http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api;http://qingqingquege.cnblogs.com/p/5933752.html;https://docs.microsoft.com/zh-cn/aspnet/mvc/overview/releases/how-to-upgrade-an-aspnet-mvc-4-and-web-api-project-