我们在用ORM(比如dapper)的时候,很多时候都需要自己写Model层(当然也有很多orm框架自带了这种功能,比如ef),特别是表里字段比较多的时候,一个Model要写半天,而且Model如果用于MVVM中,我们还需要添加PropertyChanged触发代码。发现t4模板可以自动生成代码,于是就写了一个。这个t4模板文件用了很久了,分享下。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Core.dll" #>
<#@ assembly name="System.Data.dll" #>
<#@ assembly name="System.Data.DataSetExtensions.dll" #>
<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ include file="DbHelper.ttinclude" #>
//------------------------------------------------------------------------------
// 生成时间 <#=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")#> by ly
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NFMES.Model
{ <#
string tables="CK_T_Template,CK_T_MES_MV,CK_T_MES_RPT,CK_T_MES_ROUNTINGS";
string[] ts=tables.Split(new char[]{','});
for (int i=;i<ts.Length;i++)
{
string tableName=ts[i]; #> public partial class <#= tableName #>:ModelBase {
<# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, tableName)){#> /// <summary>
/// <#=column.Remark#>
/// </summary>
private <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> _<#=column.ColumnName#> ; public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#>
{
get
{
return _<#=column.ColumnName#> ;
}
set
{
_<#=column.ColumnName#>=value;
RaisePropertyChanged("<#=column.ColumnName#>"); }
}
<#}#> }
<#
}
#>
} <#+
public class config
{
public static readonly string ConnectionString="Data Source=192.168.1.135;Initial Catalog=dbname;User ID=sa;pwd=xxx";
public static readonly string DbDatabase="dbname"; }
#>

从代码里可以看出,我们在每个生成的属性里,都添加了 RaisePropertyChanged("<#=column.ColumnName#>"),这样生成的Model也可以自动触发PropertyChanged事件了。

这一行 string tables="CK_T_Template,CK_T_MES_MV,CK_T_MES_RPT,CK_T_MES_ROUNTINGS"对应于数据库中的表名,你想将哪个表转化成Model,就将表名写这,保存下就会自动生成一个与表名一样的类。

这个t4模板引用了一个ttinclude文件,这个文件主要处理,根据表名从数据库获取表结构,字段类型等。

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core.dll" #>
<#@ assembly name="System.Data.dll" #>
<#@ assembly name="System.Data.DataSetExtensions.dll" #>
<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".txt" #> <#+
public class DbHelper
{
#region GetDbTables public static List<DbTable> GetDbTables(string connectionString, string database)
{
string tables="";
#region SQL
string sql = string.Format(@"SELECT
obj.name tablename,
schem.name schemname,
idx.rows,
CAST
(
CASE
WHEN (SELECT COUNT(1) FROM sys.indexes WHERE object_id= obj.OBJECT_ID AND is_primary_key=1) >=1 THEN 1
ELSE 0
END
AS BIT) HasPrimaryKey
from {0}.sys.objects obj
inner join {0}.dbo.sysindexes idx on obj.object_id=idx.id and idx.indid<=1
INNER JOIN {0}.sys.schemas schem ON obj.schema_id=schem.schema_id
where type='U' {1}
order by obj.name", database, tables);
#endregion
DataTable dt = GetDataTable(connectionString, sql);
return dt.Rows.Cast<DataRow>().Select(row => new DbTable
{
TableName = row.Field<string>("tablename"),
SchemaName = row.Field<string>("schemname"),
Rows = row.Field<int>("rows"),
HasPrimaryKey = row.Field<bool>("HasPrimaryKey")
}).ToList();
}
#endregion #region GetDbColumns public static List<DbColumn> GetDbColumns(string connectionString, string database, string tableName, string schema = "dbo")
{
#region SQL
string sql = string.Format(@"
WITH indexCTE AS
(
SELECT
ic.column_id,
ic.index_column_id,
ic.object_id
FROM {0}.sys.indexes idx
INNER JOIN {0}.sys.index_columns ic ON idx.index_id = ic.index_id AND idx.object_id = ic.object_id
WHERE idx.object_id =OBJECT_ID(@tableName) AND idx.is_primary_key=1
)
select
colm.column_id ColumnID,
CAST(CASE WHEN indexCTE.column_id IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey,
colm.name ColumnName,
systype.name ColumnType,
colm.is_identity IsIdentity,
colm.is_nullable IsNullable,
cast(colm.max_length as int) ByteLength,
(
case
when systype.name='nvarchar' and colm.max_length>0 then colm.max_length/2
when systype.name='nchar' and colm.max_length>0 then colm.max_length/2
when systype.name='ntext' and colm.max_length>0 then colm.max_length/2
else colm.max_length
end
) CharLength,
cast(colm.precision as int) Precision,
cast(colm.scale as int) Scale,
prop.value Remark
from {0}.sys.columns colm
inner join {0}.sys.types systype on colm.system_type_id=systype.system_type_id and colm.user_type_id=systype.user_type_id
left join {0}.sys.extended_properties prop on colm.object_id=prop.major_id and colm.column_id=prop.minor_id
LEFT JOIN indexCTE ON colm.column_id=indexCTE.column_id AND colm.object_id=indexCTE.object_id
where colm.object_id=OBJECT_ID(@tableName)
order by colm.column_id", database);
#endregion
SqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, ) { Value = string.Format("{0}.{1}.{2}", database, schema, tableName) };
DataTable dt = GetDataTable(connectionString, sql, param);
return dt.Rows.Cast<DataRow>().Select(row => new DbColumn()
{
ColumnID = row.Field<int>("ColumnID"),
IsPrimaryKey = row.Field<bool>("IsPrimaryKey"),
ColumnName = row.Field<string>("ColumnName"),
ColumnType = row.Field<string>("ColumnType"),
IsIdentity = row.Field<bool>("IsIdentity"),
IsNullable = row.Field<bool>("IsNullable"),
ByteLength = row.Field<int>("ByteLength"),
CharLength = row.Field<int>("CharLength"),
Scale = row.Field<int>("Scale"),
Remark = row["Remark"].ToString()
}).ToList();
} #endregion #region GetDataTable public static DataTable GetDataTable(string connectionString, string commandText, params SqlParameter[] parms)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand command = connection.CreateCommand();
command.CommandText = commandText;
command.Parameters.AddRange(parms);
SqlDataAdapter adapter = new SqlDataAdapter(command); DataTable dt = new DataTable();
adapter.Fill(dt); return dt;
}
} #endregion
} #region DbTable
/// <summary>
/// 表结构
/// </summary>
public sealed class DbTable
{
/// <summary>
/// 表名称
/// </summary>
public string TableName { get; set; }
/// <summary>
/// 表的架构
/// </summary>
public string SchemaName { get; set; }
/// <summary>
/// 表的记录数
/// </summary>
public int Rows { get; set; } /// <summary>
/// 是否含有主键
/// </summary>
public bool HasPrimaryKey { get; set; }
}
#endregion #region DbColumn
/// <summary>
/// 表字段结构
/// </summary>
public sealed class DbColumn
{
/// <summary>
/// 字段ID
/// </summary>
public int ColumnID { get; set; } /// <summary>
/// 是否主键
/// </summary>
public bool IsPrimaryKey { get; set; } /// <summary>
/// 字段名称
/// </summary>
public string ColumnName { get; set; } /// <summary>
/// 字段类型
/// </summary>
public string ColumnType { get; set; } /// <summary>
/// 数据库类型对应的C#类型
/// </summary>
public string CSharpType
{
get
{
return SqlServerDbTypeMap.MapCsharpType(ColumnType);
}
} public string DbType
{
get
{
return SqlServerDbTypeMap.MapDBType(ColumnType);
}
} /// <summary>
///
/// </summary>
public Type CommonType
{
get
{
return SqlServerDbTypeMap.MapCommonType(ColumnType);
}
} /// <summary>
/// 字节长度
/// </summary>
public int ByteLength { get; set; } /// <summary>
/// 字符长度
/// </summary>
public int CharLength { get; set; } /// <summary>
/// 小数位
/// </summary>
public int Scale { get; set; } /// <summary>
/// 是否自增列
/// </summary>
public bool IsIdentity { get; set; } /// <summary>
/// 是否允许空
/// </summary>
public bool IsNullable { get; set; } /// <summary>
/// 描述
/// </summary>
public string Remark { get; set; }
}
#endregion #region SqlServerDbTypeMap public class SqlServerDbTypeMap
{
public static string MapCsharpType(string dbtype)
{
if (string.IsNullOrEmpty(dbtype)) return dbtype;
dbtype = dbtype.ToLower();
string csharpType = "object";
switch (dbtype)
{
case "bigint": csharpType = "long"; break;
case "binary": csharpType = "byte[]"; break;
case "bit": csharpType = "bool"; break;
case "char": csharpType = "string"; break;
case "date": csharpType = "DateTime"; break;
case "datetime": csharpType = "DateTime"; break;
case "datetime2": csharpType = "DateTime"; break;
case "datetimeoffset": csharpType = "DateTimeOffset"; break;
case "decimal": csharpType = "decimal"; break;
case "float": csharpType = "double"; break;
case "image": csharpType = "byte[]"; break;
case "int": csharpType = "int"; break;
case "money": csharpType = "decimal"; break;
case "nchar": csharpType = "string"; break;
case "ntext": csharpType = "string"; break;
case "numeric": csharpType = "decimal"; break;
case "nvarchar": csharpType = "string"; break;
case "real": csharpType = "Single"; break;
case "smalldatetime": csharpType = "DateTime"; break;
case "smallint": csharpType = "short"; break;
case "smallmoney": csharpType = "decimal"; break;
case "sql_variant": csharpType = "object"; break;
case "sysname": csharpType = "object"; break;
case "text": csharpType = "string"; break;
case "time": csharpType = "TimeSpan"; break;
case "timestamp": csharpType = "byte[]"; break;
case "tinyint": csharpType = "byte"; break;
case "uniqueidentifier": csharpType = "Guid"; break;
case "varbinary": csharpType = "byte[]"; break;
case "varchar": csharpType = "string"; break;
case "xml": csharpType = "string"; break;
default: csharpType = "object"; break;
}
return csharpType;
} public static string MapDBType(string dbtype)
{
if (string.IsNullOrEmpty(dbtype)) return dbtype;
dbtype = dbtype.ToLower();
string csharpType = "object";
switch (dbtype)
{
case "bigint": csharpType = "DbType.Int64"; break;
case "binary": csharpType = "DbType.Binary"; break;
case "bit": csharpType = "DbType.Boolean"; break;
case "char": csharpType = "DbType.String"; break;
case "date": csharpType = "DbType.DateTime"; break;
case "datetime": csharpType = "DbType.DateTime"; break;
case "datetime2": csharpType = "DbType.DateTime2"; break;
case "datetimeoffset": csharpType = "DbType.DateTimeOffset"; break;
case "decimal": csharpType = "DbType.Decimal"; break;
case "float": csharpType = "DbType.Double"; break;
case "image": csharpType = "DbType.Binary"; break;
case "int": csharpType = "DbType.Int32"; break;
case "money": csharpType = "DbType.Currency"; break;
case "nchar": csharpType = "DbType.StringFixedLength"; break;
case "ntext": csharpType = "DbType.String"; break;
case "numeric": csharpType = "DbType.Decimal"; break;
case "nvarchar": csharpType = "DbType.String"; break;
case "real": csharpType = "DbType.Single"; break;
case "smalldatetime": csharpType = "DbType.DateTime"; break;
case "smallint": csharpType = "DbType.Int16"; break;
case "smallmoney": csharpType = "DbType.Decimal"; break;
case "sql_variant": csharpType = "DbType.Object"; break;
case "sysname": csharpType = "DbType.Object"; break;
case "text": csharpType = "DbType.String"; break;
case "time": csharpType = "DbType.DateTime"; break;
case "timestamp": csharpType = "DbType.Binary"; break;
case "tinyint": csharpType = "DbType.Byte"; break;
case "uniqueidentifier": csharpType = "DbType.Guid"; break;
case "varbinary": csharpType = "DbType.Binary"; break;
case "varchar": csharpType = "DbType.AnsiString"; break;
case "xml": csharpType = "DbType.Xml"; break;
default: csharpType = "DbType.Object"; break;
}
return csharpType;
} public static Type MapCommonType(string dbtype)
{
if (string.IsNullOrEmpty(dbtype)) return Type.Missing.GetType();
dbtype = dbtype.ToLower();
Type commonType = typeof(object);
switch (dbtype)
{
case "bigint": commonType = typeof(long); break;
case "binary": commonType = typeof(byte[]); break;
case "bit": commonType = typeof(bool); break;
case "char": commonType = typeof(string); break;
case "date": commonType = typeof(DateTime); break;
case "datetime": commonType = typeof(DateTime); break;
case "datetime2": commonType = typeof(DateTime); break;
case "datetimeoffset": commonType = typeof(DateTimeOffset); break;
case "decimal": commonType = typeof(decimal); break;
case "float": commonType = typeof(double); break;
case "image": commonType = typeof(byte[]); break;
case "int": commonType = typeof(int); break;
case "money": commonType = typeof(decimal); break;
case "nchar": commonType = typeof(string); break;
case "ntext": commonType = typeof(string); break;
case "numeric": commonType = typeof(decimal); break;
case "nvarchar": commonType = typeof(string); break;
case "real": commonType = typeof(Single); break;
case "smalldatetime": commonType = typeof(DateTime); break;
case "smallint": commonType = typeof(short); break;
case "smallmoney": commonType = typeof(decimal); break;
case "sql_variant": commonType = typeof(object); break;
case "sysname": commonType = typeof(object); break;
case "text": commonType = typeof(string); break;
case "time": commonType = typeof(TimeSpan); break;
case "timestamp": commonType = typeof(byte[]); break;
case "tinyint": commonType = typeof(byte); break;
case "uniqueidentifier": commonType = typeof(Guid); break;
case "varbinary": commonType = typeof(byte[]); break;
case "varchar": commonType = typeof(string); break;
case "xml": commonType = typeof(string); break;
default: commonType = typeof(object); break;
}
return commonType;
}
}
#endregion #>

t4文件保存后,会自动生成类文件

这样,我们省去了很多代码量。

最新文章

  1. hg 的使用简介
  2. 如何发布一个Mac应用并使其成为全球付费榜第一
  3. SQL Server 2012实施与管理实战指南(笔记)——Ch3Alwayson可用组
  4. Android Studio 生成Jar包时遇到的gradlew下载问题
  5. win7和win8如何设置快速启动栏
  6. LeetCode_implement strstr ()
  7. Spring MVC Cookie example
  8. Java阅读word程序说明文件
  9. oracle 处理时间和金额大小写的相关函数集合
  10. 最长绝对文件路径——算法面试刷题1(google),字符串处理,使用tree遍历dfs类似思路
  11. abaqus的umat在vs中debug调试
  12. 小程序实践(六):view内部组件排版
  13. better-scroll的参数和方法
  14. 伪静态与重定向--RewriteBase
  15. scrapy 关于 rule, 关于多页
  16. Go语言学习之5 进阶-排序、链表、二叉树、接口
  17. 用Matlab进行部分分式展开
  18. 李洪强iOS开发之静态库的打包一
  19. 匹配数字、字母和?%&amp;=-_这几个符号的正则表达式
  20. eclipse开发php的插件

热门文章

  1. Django视图View
  2. maven install 跳过测试
  3. 使用jenkins SVN MSBuil配置.net mvc网站进行持续集成
  4. JVM 理解
  5. 12 MySQL--内置功能介绍
  6. [C++] STL相关面试题
  7. leetcode 1 A+B problems
  8. Django基础学习六之渲染
  9. SuSE 网卡配置模板
  10. mybatis框架入门程序:演示通过mybatis实现数据库的插入操作中实现返回结果的获取