DbModel

前言

我们都知道EF可以生成Dbmodel,系统生成的Model有时候并不是我们想要的,如何我们要生成自己的Model,那么久需要我们手动的去修改T4模版,T4是对“Text Template Transformation Toolkit”(4个T)的简称。如果你对T4不怎么了解可以去看蒋金楠(Artech)文章从数据到代码——基于T4的代码生成方式

1.0先看看我们要达到的效果图吧

2.0首先我们来修改T4模版吧

打开T4模版,找到代码 WriteHeader(codeStringGenerator, fileManager);

我们首先定义变量(图中黄色代码为我们自己添加的代码)

WriteHeader(codeStringGenerator, fileManager);
string summary=string.Empty; 定义变量
foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
fileManager.StartNewFile(entity.Name + ".cs");
BeginNamespace(code);
if(entity.Documentation !=null && entity.Documentation.Summary!=null)
summary=entity.Documentation.Summary;
else
summary=entity.Name;
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
using System.ComponentModel.DataAnnotations; 导入你需要的命名空间 /// <summary>
/// <#= summary#>给类加注释
/// </summary>
[Serializable]
<#=codeStringGenerator.EntityClassOpening(entity)#>

看看效果图如下:

类上面的注释已经加好了,接下来就是删除构造函数,删除以下代码即可:

    public <#=code.Escape(entity)#>()
{
<#
foreach (var edmProperty in propertiesWithDefaultValues)
{
#>
this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
<#
} foreach (var navigationProperty in collectionNavigationProperties)
{
#>
this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
<#
} foreach (var complexProperty in complexProperties)
{
#>
this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
<#
}
#>
}

接下来我们把这些可空类型还原成本来面目,已经去掉virtual关键字,修改代码如下:

public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
{
if (edmType == null)
{
return null;
} var collectionType = edmType as CollectionType;
if (collectionType != null)
{
return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
} var typeName = _code.Escape(edmType.MetadataProperties
.Where(p => p.Name == ExternalTypeNameAttributeName)
.Select(p => (string)p.Value)
.FirstOrDefault())
?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
_code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
_code.Escape(edmType)); if (edmType is StructuralType)
{
return typeName;
} if (edmType is SimpleType)
{
var clrType = UnderlyingClrType(edmType);
if (!IsEnumType(edmType))
{
typeName = _code.Escape(clrType);
} typeName = FixNamespaces(typeName); return clrType.IsValueType && isNullable == true ?
// String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :原来的代码
String.Format(CultureInfo.InvariantCulture, "{0}?", typeName) :自己修改的代码
typeName;
} throw new ArgumentException("edmType");
}
   public string NavigationProperty(NavigationProperty navigationProperty)
{
var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"public {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)),
navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navigationProperty),
_code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
_code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
}

接下来来给属性上添加注释:(橙色代码删除,皇色代码添加)

/// <summary>
/// <#= summary#>
/// </summary>
[Serializable]
<#=codeStringGenerator.EntityClassOpening(entity)#>
{
<#
var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
var complexProperties = typeMapper.GetComplexProperties(entity); if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
{
#> <#
}删除掉代码 var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
foreach (var edmProperty in simpleProperties)
{ if (edmProperty.Documentation != null && edmProperty.Documentation.Summary != null)
{
if(!entity.KeyMembers.Contains(edmProperty.Name))
summary=edmProperty.Documentation.Summary.ToLower().Replace("id","名称");
else
summary=edmProperty.Documentation.Summary;
}
else
{
summary="";
} #> <# //if(edmProperty.Name.ToLower() == "id")
// continue;var a=edmProperty.Nullable; var keyName="";
if(entity.KeyMembers.Contains(edmProperty.Name))
keyName="[Key]";
var required="";
if(!edmProperty.Nullable)
required="[Required(ErrorMessage = \"请输入{0}\")]";
string facetName = "MaxLength";
var lengthDes="";
var stringLengthDes="";
int maxLength = 0;
if (code.Escape(edmProperty.TypeUsage).ToLower().Contains("string") && Int32.TryParse(edmProperty.TypeUsage.Facets[facetName].Value.ToString(), out maxLength)){
lengthDes="[MaxLength("+maxLength+")]";
stringLengthDes="[StringLength("+maxLength+")]";
}
var dataType="";
if (code.Escape(edmProperty.TypeUsage).ToLower().Contains("datetime"))
dataType="[DataType(DataType.DateTime)]";
else if (edmProperty.Name.ToLower().Contains("password"))
dataType="[DataType(DataType.Password)]"; #>
/// <summary>
/// <#= summary#>
/// </summary>
<# if(!string.IsNullOrWhiteSpace(required)){ #>
<#= required #>
<# } if(!string.IsNullOrWhiteSpace(summary)){ #>
<#= "[Display(Name = \""+summary+"\")]" #>
<# } if(!string.IsNullOrWhiteSpace(lengthDes)){ #>
<#= lengthDes #>
<# } if(!string.IsNullOrWhiteSpace(stringLengthDes)){ #>
<#= stringLengthDes #>
<# } if(!string.IsNullOrWhiteSpace(dataType)){ #>
<#= dataType #>
<# } if(!string.IsNullOrWhiteSpace(keyName)){ #>
<#= keyName #>
<# } #>
<#=codeStringGenerator.Property(edmProperty)#>

效果基本已经差不多,可是这里为什么没有注释,园子里已经有其他文章来处理这个问题:

1.0EF架构~将数据库注释添加导入到模型实体类中 2.0entity framework框架生成摘要文档为空(没有元数据文档可用)的bug解决方案

按照步骤做了,可是问题还是没有解决,怎么办,其实根本原因是:

主要原因是这里的摘要没有数据。不断的尝试啊,entity framework框架生成摘要文档为空(没有元数据文档可用)的bug解决方案 试了几次还是没有从根本上解决问题,怎么办了...

3.0解决bug

没办法我们查看EFTSQLDocumentation.Generator的源码终于找到问题所在

        public String ConnectionString { get; set; }
public String InputFileName { get; set; }
public String OutputFileName { get; set; } private SqlConnection _connection; public Program(String connectionString, String inputFileName, String outputFileName)
{
this.ConnectionString = connectionString;
this.InputFileName = inputFileName;
this.OutputFileName = outputFileName; this._connection = new SqlConnection(connectionString);
this._connection.Open();
}
public void Dispose()
{
this._connection.Dispose();
} private void CreateDocumentation()
{ XDocument doc = XDocument.Load(this.InputFileName);
IEnumerable<XElement> entityTypeElements = doc.Descendants("{http://schemas.microsoft.com/ado/2008/09/edm}EntityType"); int i = 0;
foreach (XElement entityTypeElement in entityTypeElements)
{
String tableName = entityTypeElement.Attribute("Name").Value;
IEnumerable<XElement> propertyElements = entityTypeElement.Descendants("{http://schemas.microsoft.com/ado/2008/09/edm}Property"); Console.Clear();
Console.WriteLine("Analyzing table {0} of {1}", i++, entityTypeElements.Count());
Console.WriteLine(" => TableName : {0}" +
"\n => property count : {1}", tableName, propertyElements.Count()); this.AddNodeDocumentation(entityTypeElement, GetTableDocumentation(tableName)); foreach (XElement propertyElement in propertyElements)
{
String columnName = propertyElement.Attribute("Name").Value;
this.AddNodeDocumentation(propertyElement, GetColumnDocumentation(tableName, columnName));
}
} Console.WriteLine("Writing result to {0}", this.OutputFileName);
if (File.Exists(this.OutputFileName))
File.Delete(this.OutputFileName);
doc.Save(this.OutputFileName);
}
private void AddNodeDocumentation(XElement element, String documentation)
{
if (String.IsNullOrEmpty(documentation))
return;
element.Descendants("{http://schemas.microsoft.com/ado/2008/09/edm}Documentation").Remove(); element.AddFirst(new XElement("{http://schemas.microsoft.com/ado/2008/09/edm}Documentation", new XElement("{http://schemas.microsoft.com/ado/2008/09/edm}Summary", documentation)));
}
private String GetTableDocumentation(String tableName)
{
using (SqlCommand command = new SqlCommand(@" SELECT [value]
FROM fn_listextendedproperty (
'MS_Description',
'schema', 'dbo',
'table', @TableName,
null, null)", this._connection))
{ command.Parameters.AddWithValue("TableName", tableName); return command.ExecuteScalar() as String;
}
}
private String GetColumnDocumentation(String tableName, String columnName)
{
using (SqlCommand command = new SqlCommand(@"SELECT [value]
FROM fn_listextendedproperty (
'MS_Description',
'schema', 'dbo',
'table', @TableName,
'column', @columnName)", this._connection))
{ command.Parameters.AddWithValue("TableName", tableName);
command.Parameters.AddWithValue("ColumnName", columnName); return command.ExecuteScalar() as String;
}
}

我们的edmx中的代码如下:

      <Schema Namespace="yaochufaNewTestModel.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2008" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityType Name="Activities">
<Key>
<PropertyRef Name="ActivityId" />
</Key>
<Property Name="ActivityId" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="ActivityType" Type="int" Nullable="false" />
<Property Name="ProvinceId" Type="int" />
<Property Name="CityId" Type="int" />
<Property Name="Description" Type="nvarchar" MaxLength="50" />
<Property Name="IsActive" Type="bit" Nullable="false" />
<Property Name="EndDate" Type="datetime" />
<Property Name="StartDate" Type="datetime" />
<Property Name="DrawDate" Type="datetime" />
<Property Name="DrawInfo" Type="nvarchar" MaxLength="1000" />
<Property Name="LimitTime" Type="int" />
<Property Name="ShowStartDate" Type="datetime" />
<Property Name="ShowEndDate" Type="datetime" />
<Property Name="PrizeCount" Type="int" />
<Property Name="ModifiedById" Type="int" />
<Property Name="ModifiedByName" Type="nvarchar" MaxLength="50" />
<Property Name="ModifiedDate" Type="datetime" />
<Property Name="CreatedById" Type="int" Nullable="false" />
<Property Name="CreatedByName" Type="nvarchar" MaxLength="50" Nullable="false" />
<Property Name="CreatedDate" Type="datetime" Nullable="false" />
</EntityType>

需要修改的就是EFTSQLDocumentation.Generator源码中的xml命名空间我们要替换成 http://schemas.microsoft.com/ado/2009/11/edm最终在cmd中运行如下代码:

EFTSQLDocumentation.Generator.exe -c "data source=.;initial catalog=yaochufaNewTest;user id=sa;password=123;" -i " D:\Feng.Test\Feng.Test\Model1.edmx"

得到效果图如下:

DbModel的更多相关文章

  1. EF架构随心所欲打造属于你自己的DbModel【转】

    前言 我们都知道EF可以生成Dbmodel,系统生成的Model有时候并不是我们想要的,如何我们要生成自己的Model,那么久需要我们手动的去修改T4模版,T4是对“Text Template Tra ...

  2. Did you forget about DBModel.InitializeModel the model [AAAdm] ?

    AIO5安装完毕后登陆出现以下报错:Did you forget about DBModel.InitializeModel the model [AAAdm] ? 说明: 执行当前 Web 请求期间 ...

  3. [原创]EF架构随心所欲打造属于你自己的DbModel

    前言 我们都知道EF可以生成Dbmodel,系统生成的Model有时候并不是我们想要的,如何我们要生成自己的Model,那么久需要我们手动的去修改T4模版,T4是对“Text Template Tra ...

  4. AntData.ORM框架 之DBModel CodeGen如何使用

    AntData.ORM 框架 开源地址:https://github.com/yuzd/AntData.ORM 打开VS2015 打开Tools =>Extentions and Updates ...

  5. iOS---基于对Sqlilte3的二次包装的第三次包装--->JKDBModel ,一个好用的离线缓存库

    https://github.com/Joker-King/JKDBModel 1.将FMDB和DBModel拖入项目中,然后添加libsqlite3.dylib   2. #import " ...

  6. Django简单的数据库操作

    当然,本篇的前提是你已经配置好了相关的环境,这里就不详细介绍. 一. 在settings.py文件中设置数据库属性. 如下: DATABASES = { 'default': { 'ENGINE': ...

  7. spring mvc+mybatis+sql server简单配置

    context.xml配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&qu ...

  8. monodb C#接口封装

    mongodb的C#封装,驱动是samus/mongodb-csharp 1.连接类 using MongoDB; using MongoDB.Linq; namespace DBModel { pu ...

  9. 项目中初试PHP单元测试

    只能叫初试,前面虽然做了一些PHPUnit与团队所用框架的整合,但在整个团队还没有人可以主动推动这个事情,而作为Leader最重要的一种能力应该是"让正确的事情发生",所以今天开始 ...

随机推荐

  1. 阿里2015回顾面试招收学历(获得成功offer)

    1. 引言 继上次"百度2015校园招聘面试题回顾录(成功拿到offer)"文章过后,大家都希望除了题目之外.最好能给出自己当时的回答情况,看看有没有什么回答技巧,这样更有參考价值 ...

  2. POJ1274_The Perfect Stall(二部图最大匹配)

    解决报告 http://blog.csdn.net/juncoder/article/details/38136193 id=1274">题目传送门 题意: n头m个机器,求最大匹配. ...

  3. C# WinForm 拖动无边框窗体 改变无边框窗体尺寸

    经常遇到这种情况.窗体的边框去掉了.然后种种问题就出来了:不能拖动.不能改变窗体大小.不能......当然.肯定有解决方案滴*^_^*今天的目标就是:可以直接拖动没有边框的窗体.可以直接拉拽窗体改变其 ...

  4. Mysql 5.6 新特性

    随笔,真的随笔,以后理解得更深了再修改.   Index Condition Pushdown 更多的让存储引擎去处理Where语句中的条款,避免返回无关字段数据等:   Multi-Range Re ...

  5. NBA球员 ESPN前20排名:詹姆斯再居榜首

    2014年 ESPN球员实力最后排名 没想到 保罗-乔治没有上榜.之前预測的火箭两大明星排名落后了,杜兰特排到第8有点出乎意料. 戴维斯升得那么快有点出乎意料,一个球队拥有两位排前十位的球队:骑士,快 ...

  6. mysql数据文件迁移到新的硬盘分区的方法

    该系统增加了一个硬盘.要创建新的分区/data文件夹,mysql对于数据文件夹/var/lib/mysql 1.  停止mysql维修 [root@localhost~]# service mysql ...

  7. 编写爬虫程序的神器 - Groovy + Jsoup + Sublime(转)

    写过很多个爬虫小程序了,之前几次主要用C# + Html Agility Pack来完成工作.由于.NET FCL只提供了"底层"的HttpWebRequest和"中层& ...

  8. WP8加入自己定义铃声

    1.下载千千静听绿色版,下载地址:http://pan.baidu.com/s/1ntuSNOH 2.将目标铃声加入到千千静听,选中铃声,右键选文件属性. 3.改动文件属性,将流派改为"Ri ...

  9. Google调试技巧总结

    工欲善其事 工欲善其事,必先利器. Google调试面板一一介绍:F12回想一下大家都应该知道,哈哈 element面板 这个面板显示了页面所有html代码.用于调试css代码.右側展示左側相应选择元 ...

  10. Controller 里面就只应该存放这些不能复用的代码(转)

    MVC 的历史 MVC,全称是 Model View Controller,是模型 (model)-视图 (view)-控制器 (controller) 的缩写.它表示的是一种常见的客户端软件开发框架 ...