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最重要的一种能力应该是"让正确的事情发生",所以今天开始 ...
随机推荐
- 使用Python做科学计算初探(转)
今天在搞定Django框架的blog搭建后,尝试一下python的科学计算能力. python的科学计算有三剑客:numpy,scipy,matplotlib. numpy负责数值计算,矩阵操作等: ...
- 【cocos2d-js官方文档】二十五、Cocos2d-JS v3.0中的单例对象
为何将单例模式移除 在Cocos2d-JS v3.0之前.全部API差点儿都是从Cocos2d-x中移植过来的,这是Cocos2d生态圈统一性的重要一环.可惜的是,这样的统一性也在非常大程度上限制了C ...
- linux学习(一个) 在unbuntu通过添加新的用户
最近安装了双系统,开始折腾unbuntu该.Linux系统是一个多用户操作系统,非常多的人才完整的操作需要管理员权限,完全管理员权限是非常重要的.人谁是刚开始学习,般用户的权限即可了,相对于刚開始学习 ...
- 何时使用SET和SELECT为变量赋值
原文:何时使用SET和SELECT为变量赋值 我们经常使用SET和SELECT来为变量复制,但是有时候,只能选其一来使用,下面来看看这些例子,本例中使用AdventureWorks数据库来做演示. 通 ...
- iPhone&iPad DFU及恢复模式刷机、降级教程
再次提醒,刷机需慎重处理. http://blog.csdn.net/ztp800201/article/details/11980643 iphone一共同拥有三种工作模式,各自是正常模式,恢复模式 ...
- Git--Submodule使用
项目模板中通常由前端保持,所以每次更新模板.我也要跟着变化项目. 随着时间的推移,这不是一个方法来找到,老这么维护.大型项目,更多的模板,真的很容易管理和维护. 然后头让我用submodule前端资源 ...
- SQL Server 移动数据库
原文:SQL Server 移动数据库 移动系统数据库在下列情况下可能很有用: 故障恢复.例如,数据库处于可疑模式下或因硬件故障而关闭. 计划的重定位. 为预定的磁盘维护操作而进行的重定位. 下列过程 ...
- Spring 通过来AOP 实现前置,环绕,异常通知,注解(转)
本节主要内容: 1. Spring AOP前置通知案例 2. Spring AOP环绕通知案例 3. Spring AOP异常通知案例 4. Spring AOP注解使 ...
- 于ubuntu配置hadoop当问题
1. 构造ssh登录 我们并不需要改变/etc/ssh/sshd_config 2. 新hadoop用户,home下列不hadoop夹 创建使用下面的命令 useradd -m hadoop 3. n ...
- Struts2+Spring+Hibernate step by step 11 ssh拦截验证用户登录到集成
注意:该系列文章从教师王健写了一部分ssh集成开发指南 引言: 之前没有引入拦截器之前,我们使用Filter过滤器验证用户是否登录,在使用struts2之后,全然能够使用拦截器,验证用户是否已经登录, ...