DbModel
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的更多相关文章
- EF架构随心所欲打造属于你自己的DbModel【转】
前言 我们都知道EF可以生成Dbmodel,系统生成的Model有时候并不是我们想要的,如何我们要生成自己的Model,那么久需要我们手动的去修改T4模版,T4是对“Text Template Tra ...
- Did you forget about DBModel.InitializeModel the model [AAAdm] ?
AIO5安装完毕后登陆出现以下报错:Did you forget about DBModel.InitializeModel the model [AAAdm] ? 说明: 执行当前 Web 请求期间 ...
- [原创]EF架构随心所欲打造属于你自己的DbModel
前言 我们都知道EF可以生成Dbmodel,系统生成的Model有时候并不是我们想要的,如何我们要生成自己的Model,那么久需要我们手动的去修改T4模版,T4是对“Text Template Tra ...
- AntData.ORM框架 之DBModel CodeGen如何使用
AntData.ORM 框架 开源地址:https://github.com/yuzd/AntData.ORM 打开VS2015 打开Tools =>Extentions and Updates ...
- iOS---基于对Sqlilte3的二次包装的第三次包装--->JKDBModel ,一个好用的离线缓存库
https://github.com/Joker-King/JKDBModel 1.将FMDB和DBModel拖入项目中,然后添加libsqlite3.dylib 2. #import " ...
- Django简单的数据库操作
当然,本篇的前提是你已经配置好了相关的环境,这里就不详细介绍. 一. 在settings.py文件中设置数据库属性. 如下: DATABASES = { 'default': { 'ENGINE': ...
- spring mvc+mybatis+sql server简单配置
context.xml配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&qu ...
- monodb C#接口封装
mongodb的C#封装,驱动是samus/mongodb-csharp 1.连接类 using MongoDB; using MongoDB.Linq; namespace DBModel { pu ...
- 项目中初试PHP单元测试
只能叫初试,前面虽然做了一些PHPUnit与团队所用框架的整合,但在整个团队还没有人可以主动推动这个事情,而作为Leader最重要的一种能力应该是"让正确的事情发生",所以今天开始 ...
随机推荐
- Centos6.5下一个Ceph存储集群结构
简单的介绍 Ceph的部署模式下主要包括下面几个类型的节点 • Ceph OSDs: A Ceph OSD 进程主要用来存储数据,处理数据的replication,恢复,填充.调整资源组合以及通过检查 ...
- ym——Android之ListView性能优化
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! Android之ListView性能优化 假设有看过我写过的15k面试题的朋友们一定知 ...
- 移动端 transition动画函数的封装(仿Zepto)以及 requestAnimationFrame动画函数封装(仿jQuery)
移动端 css3 transition 动画 ,requestAnimationFrame 动画 对于性能的要求,h5优先考虑: 移动端 单页有时候 制作只用到简单的css3动画即可,我们封装一下, ...
- osx下一个MobileBackups简介
自从开启了mac的TimeMachine之后,使用了一段时间的mac磁盘空间降低的非常多,于是使用du -d1(disk usage and depth is one)命令查看/文件夹空间的使用情况, ...
- 相关Python分割操作
刚论坛python文本 http://bbs.byr.cn/#!article/Python/1693 攻克了一个关于python分片的问题. 问题: uesrList = ['1','2','3', ...
- hdu 4465 概率称号
http://acm.hdu.edu.cn/showproblem.php?pid=4465 第一直觉概率DP但很快被否定,发现只有一个简单的二项分布,但感情的表达,没有对生命和死亡的例子.然后找到准 ...
- 【 D3.js 入门系列 --- 10.2 】 你可以拖动地图
我的个人博客是:www.ourd3js.com csdn博客为:blog.csdn.net/lzhlzz 转载请注明出处.谢谢. 本节是结合9.2节 和10节 的内容制作的一个可力学导向的中国地图,用 ...
- Base64中文不能加密问题
最近用到了Base64.js来对url参数进行加密,字母和数字都可以很好地加密/解密. 但测试中文时发现不能进行转换,貌似Base64.js不支持中文字符. 联想到encodeURI()对url的编码 ...
- linux下面的中断处理软件中断tasklet机制
參考: <Linux内核设计与实现> http://blog.csdn.net/fontlose/article/details/8279113 http://blog.chinaunix ...
- 【年终分享】彩票数据预测算法(一):离散型马尔可夫链模型实现【附C#代码】
原文:[年终分享]彩票数据预测算法(一):离散型马尔可夫链模型实现[附C#代码] 前言:彩票是一个坑,千万不要往里面跳.任何预测彩票的方法都不可能100%,都只能说比你盲目去买要多那么一些机会而已. ...