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. leetcode第一刷_Minimum Path Sum

    能够用递归简洁的写出,可是会超时. dp嘛.这个问题须要从后往前算,最右下角的小规模是已知的,边界也非常明显,是最后一行和最后一列,行走方向的限制决定了这些位置的走法是唯一的,能够先算出来.然后不断的 ...

  2. URAL - 1966 - Cycling Roads(并检查集合 + 判刑线相交)

    意甲冠军:n 积分,m 边缘(1 ≤ m < n ≤ 200),问:是否所有的点连接(两个边相交.该 4 点连接). 主题链接:http://acm.timus.ru/problem.aspx? ...

  3. CSS 之 光进入光

    一个.概念 css,层叠样式表(英语:Cascading Style Sheets.简写CSS).又称串样式列表.层次结构式样式表文件,一 种用来为结构化文档(如HTML文档或XML应用)加入样式(字 ...

  4. http协议和web本质(转)

    当你在浏览器地址栏敲入“http://www.cnblogs.com/”,然后猛按回车,呈现在你面前的,将是博客园的首页了(这真是废话,你会认为这是理所当然的).作为一个开发者,尤其是web开发人员, ...

  5. 4安德鲁斯.2.2在系统,具有系统权限的应用程序无法读取或写入SD卡

    有两个解决方案: 1.通过改动android系统的源代码,开放SD卡的读写权限,具体的改动方法和说明.能够參考网上资料http://www.ifeegoo.com/android-debug-stat ...

  6. vs2015基于VisualStudioOnline协同工作流程

    项目负责人登陆自己的vsonline新建项目就不多说了. 直接从邀请队友开始 项目负责人操作 被邀请的邮箱务必是可以登录visualstudio的邮箱 发送邀请后,被邀请人登陆自己的邮箱,查看邀请人发 ...

  7. ZipDemo

    package swing.zip; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt. ...

  8. BZOJ 1096 ZJOI2007 仓库建设 边坡优化

    标题效果:特定n植物,其中一些建筑仓库,有一点使,假设没有仓库仓库向右仓库.最低消费要求 非常easy边坡优化--在此之前刷坡优化的情况下,即使这道题怎么错过 订购f[i]作为i点建设化妆i花费所有安 ...

  9. KVO 其原理探究

    什么是KVO ? KVO这是Key-Value Observing,它提供了一种机制,指定的对象的属性被改动后,则对象就会接受到通知. 简单的说就是每次指定的被观察的对象的属性被改动后.KVO就会自己 ...

  10. Android studio 中国的垃圾问题解决

    为了获得良好的刚安装Android studio, 实例importproject时刻,你会发现很多中国的文件夹显示异常.例如下面的附图: 为什么会出现这个问题呢,事实上原因非常easy,由于Andr ...