VS2010,MVC3,CodeFirst
一般的开发流程是设计数据库,然后编写实体类的DatabaseFirst模式.即使现在CodeFirst很流行,即首先编写实体类然后生成数据库,但是实体之间的关系通过DbContext中的OnModelCreating事件来手动编写还是很麻烦的.因此很多开发还是习惯通过PD设计数据库.那么如何生成我们需要的CodeFirst的实体类呢.并且我们实体类的如何包含在PD中已经设置了中文描述如[Display(Name="编号")]这样的属性呢.
在PD的设计中我们是包含字段的中文名的(如上图)
打开菜单=>数据库=>Generate Database
在Options中勾选Table和Column的comment复选框
在Format中勾选Title和Generate name in empty comment
至此我们可以通过执行sql来生成带有字段说明的数据库了.
首先我们添加一个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文件里面是不包含摘要和长说明的.
添加摘要查了很多文章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属性的
模版是通过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; }
做开发也很多年了一直在研究如何快速开发,除了优化架构使代码更方便编写外我们也应该多利用现有的代码模版来快速生成代码.
希望本文能对大家有所帮助,从编写实体类的繁琐工作中解放出来:)