【開發環境】
VS2010,MVC3,CodeFirst
【背景】
一般的開發流程是設計數據庫,然后編寫實體類的DatabaseFirst模式.即使現在CodeFirst很流行,即首先編寫實體類然后生成數據庫,但是實體之間的關系通過DbContext中的OnModelCreating事件來手動編寫還是很麻煩的.因此很多開發還是習慣通過PD設計數據庫.那么如何生成我們需要的CodeFirst的實體類呢.並且我們實體類的如何包含在PD中已經設置了中文描述如[Display(Name="編號")]這樣的屬性呢.
【1、通過PD生成數據庫】
在PD的設計中我們是包含字段的中文名的(如上圖)
打開菜單=>數據庫=>Generate Database
在Options中勾選Table和Column的comment復選框
在Format中勾選Title和Generate name in empty comment
至此我們可以通過執行sql來生成帶有字段說明的數據庫了.
【2、實現通過數據庫生成實體類】
首先我們添加一個edmx文件
選擇通過數據庫生成,直到完成.
添加代碼生成項
選擇ADO.NET C# DbContext Generator,如果沒有的話我們可以在下面的聯機查詢中搜索.點擊添加后我們則生成了實體類和DbContext類,並且如果用ADO.NET C# DbContext Fluent Generator的話則也會生成Fuent mapping classes.但是這樣的實體類是沒有DataAnnotations的.因此我們需要能夠生成DataAnnotations的生成模版.
POCO Generator With Validations.這樣我們生成的代碼是包含基本的[Required]這樣的屬性的,但是沒有我們需要的Diaplay的屬性.
這時我們會發現我們的模版數據是通過edmx文件來的,但是我們的edmx文件里面是不包含摘要和長說明的.
【3、給EDMX文件添加摘要】
添加摘要查了很多文章https://connect.microsoft.com/VisualStudio/feedback/details/498313/retrieve-the-sql-descriptions-in-entity-framework.最終發現通過vs2010提供的功能是不能實現了,不過還好codeplex上已經有人給出了解決方案http://eftsqldocgenerator.codeplex.com/.
它是通過獲取數據庫字段的說明然后修改EDMX文件來實現的.
具體命令如下:
EFTSQLDocumentation.Generator.exe –c “ConnectionString” –i “edmx input File”
把ConnectionString替換成你的數據庫連接字符串,edmx input File替換成你的edmx文件路徑,主要全角半角.
命令執行完成我們在看EDMX文件的字段就是包含字段說明的:
我們EDMX文件已被修改為:
<EntityType Name="DWSectionPlaces"> <Documentation> <Summary>分段表</Summary> </Documentation> <Key> <PropertyRef Name="ID" /> </Key> <Property Name="ID" Type="String" Nullable="false" MaxLength="20" Unicode="false" FixedLength="false"> <Documentation> <Summary>ID</Summary> </Documentation> </Property> <Property Name="ApplyOrgID" Type="String" MaxLength="20" Unicode="false" FixedLength="false"> <Documentation> <Summary>申請部門</Summary> </Documentation> </Property>
我們重新生成我們的實體代碼,這時還是沒有Display屬性的
【4、修改生成模版添加Diplay屬性支持】
模版是通過EntityType來描述實體類型的,我們通過msdn查詢可以找到他的摘要對應的字段為edmProperty.Documentation.Summary.
因為我們修改T4模版加入下面標紅的代碼:
<#
string facetName = "MaxLength";
int maxLength = 0;
if(!edmProperty.Nullable)
{
WriteLine("[Required]");
}
else
{
WriteLine("//[Required]");
}
if (code.Escape(edmProperty.TypeUsage) == "string" && Int32.TryParse(edmProperty.TypeUsage.Facets[facetName].Value.ToString(), out maxLength))
{
WriteLine("{0}[MaxLength({1})]",CodeRegion.GetIndent(1),maxLength);
}
if(edmProperty.Documentation!=null&&!string.IsNullOrEmpty(edmProperty.Documentation.Summary))
{
WriteLine("{0}[Display(Name = \""+edmProperty.Documentation.Summary+"\")]",CodeRegion.GetIndent(1));
}
#>
至此我們重新生成實體類則已經包含中文Display屬性.
[Required] [MaxLength(20)] [Display(Name = "ID號")] public virtual string ID { get; set; }
【總結】
做開發也很多年了一直在研究如何快速開發,除了優化架構使代碼更方便編寫外我們也應該多利用現有的代碼模版來快速生成代碼.
希望本文能對大家有所幫助,從編寫實體類的繁瑣工作中解放出來:)