对于C#面向对象的思想,我们习惯于将数据库中的表创建对应的数据模型;

但假如数据表很多时,我们手动增加模型类会显得很浪费时间;

这个时候有些人会用微软提供的EntityFrameWork,这个框架很强大,编写代码效率也很高,但很由于性能差,在复杂查询的时候生成的sql脚本效率不是很高,所以有的时候不会去使用它;

这个时候就会有CodeSmith来协助我们去完成那些费时费力的工作:

CodeSmith如何使用,网上也有很详细的介绍了,下面代码只是简单介绍

属性SourceDataBase是连接的数据库,CodeSmith提供连接数据库的方法很方便

属性NameSpace顾名思义就是命名空间

 <%--
Name:批量生成实体类
Author: TitanChen
Description:批量将数据库中的表结构生成数据模型
--%>
<%@ CodeTemplate Language="C#" TargetLanguage="C#" Description="Template description here." %>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Import Namespace="SchemaExplorer" %>
<%@ Property Name="SourceDatabase" Type="SchemaExplorer.DatabaseSchema" Category="Context" %>
<%@ Property Name="NameSpace" Type="String" Category="参数" Description="命名空间" Default="Blog.Core.Model" Optional="True"%>
<%@ Import Namespace="System.Text.RegularExpressions" %>
using System;
using System.Collections.Generic;
using System.Text; namespace <%=NameSpace%>
{
<% foreach(TableSchema SourceTable in SourceDatabase.Tables) { %>
/// <summary>
/// <%=GetClassName(SourceTable) +"模型"%>
/// </summary>
[Serializable]
public class <%=GetClassName(SourceTable) %> : BaseModel
{
/// <summary>
/// 表名
/// </summary>
public static readonly string TableName = "<%=GetClassName(SourceTable) %>"; /// <summary>
/// 构造函数
/// </summary>
public <%=GetClassName(SourceTable) %>() : base(TableName)
{
} private Guid Id = Guid.Empty;
<% foreach (ColumnSchema column in SourceTable.Columns) {%>
/// <summary>
/// <%=column.Description %>
/// </summary>
<% if(column.IsPrimaryKeyMember){ %>
public Guid <%= GetPascalName(column) %>
{
get{ return Id;}
set
{
Id = value;
if (value != null)
{
base.BaseId = value;
}
}
} <% }else{ %>
public <%=GetCSharpVariableType(column) %> <%=GetPascalName(column) %> { get; set; } <% } %>
<% }%>
} /// <summary>
/// <%=GetClassName(SourceTable) +"数据模型"%>
/// </summary>
[Serializable]
public class <%=GetClassName(SourceTable)+"ListData" %>
{
/// <summary>
/// 总记录数
/// </summary>
public int RecordCount { get; set; } /// <summary>
/// 数据列表
/// </summary>
public List<<%=GetClassName(SourceTable)+"ListModel" %>> RecordList { get; set; }
} /// <summary>
/// <%=GetClassName(SourceTable) +"列表模型"%>
/// </summary>
[Serializable]
public class <%=GetClassName(SourceTable)+"ListModel" %>
{
<% foreach (ColumnSchema column in SourceTable.Columns) {%>
<%if(new string[]{"IsDeleted"}.Contains(column.Name)){continue;} %>
/// <summary>
/// <%=column.Description %>
/// </summary>
public <%=GetCSharpVariableType(column)=="Guid" || GetCSharpVariableType(column)=="DateTime"?"string":GetCSharpVariableType(column) %> <%=GetPascalName(column) %> { get; set; } <% }%>
}
<%} %>
}
<script runat="template"> public string MakeSingle(string name)
{
return name;
}
public string GetCamelName(ColumnSchema column)
{
return column.Name.Substring(, ).ToLower() + column.Name.Substring();
}
public string GetCamelName(string value)
{
return value.Substring(, ).ToLower() + value.Substring();
}
public string GetPascalName(ColumnSchema column)
{
return column.Name.Substring(, ).ToUpper() + column.Name.Substring();
}
public string GetPascalName(string value)
{
return value.Substring(, ).ToUpper() + value.Substring();
}
public string GetClassName(TableSchema table)
{
return GetPascalName(MakeSingle(table.Name));
}
public string GetForeignKeyColumnType(ColumnSchema column)
{
return column.Table.ForeignKeys[].PrimaryKeyTable.Name;
}
public string GetForeignKeyColumnName(ColumnSchema column)
{
if(column.Name.Substring(column.Name.Length-).ToLower() == "id")
{
return column.Name.Substring(,column.Name.Length-);
}
else
{
return column.Name;
}
}
public string GetPrimaryKeyType(TableSchema table)
{
if (table.PrimaryKey != null)
{
if (table.PrimaryKey.MemberColumns.Count == )
{
return GetCSharpVariableType(table.PrimaryKey.MemberColumns[]);
}
else
{
throw new ApplicationException("This template will not work on primary keys with more than one member column.");
}
}
else
{
throw new ApplicationException("This template will only work on tables with a primary key.");
}
}
public string GetCSharpVariableType(ColumnSchema column)
{
if (column.Name.EndsWith("TypeCode")) return column.Name; switch (column.DataType)
{
case DbType.AnsiString: return "string";
case DbType.AnsiStringFixedLength: return "string";
case DbType.Binary: return "byte[]";
case DbType.Boolean: return "bool";
case DbType.Byte: return "byte";
case DbType.Currency: return "decimal";
case DbType.Date: return "DateTime";
case DbType.DateTime: return "DateTime";
case DbType.Decimal: return "decimal";
case DbType.Double: return "double";
case DbType.Guid: return "Guid";
case DbType.Int16: return "short";
case DbType.Int32: return "int";
case DbType.Int64: return "long";
case DbType.Object: return "object";
case DbType.SByte: return "sbyte";
case DbType.Single: return "float";
case DbType.String: return "string";
case DbType.StringFixedLength: return "string";
case DbType.Time: return "TimeSpan";
case DbType.UInt16: return "ushort";
case DbType.UInt32: return "uint";
case DbType.UInt64: return "ulong";
case DbType.VarNumeric: return "decimal";
default:
{
return "__UNKNOWN__" + column.NativeType;
}
}
}
</script>

 CodeSmith虽然方便,但是要安装和激活,这个是很麻烦的;而且每次生成都要打开CodeSmith去生成,不是很方便;

于是我就照着原先在CodeSmith上模板写了个控制台应用程序,可以改写配合着bat使用,贼方便

 using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Linq;
using System.IO; namespace Blog.Core.Test
{
public class Program
{
/// <summary>
/// 数据库连接字符串
/// </summary>
private static string _connstr = "Data Source=localhost;Initial Catalog=Test;User Id=sa;Password=123456"; /// <summary>
/// 主函数
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.Write("命名空间:");
string namespaces = Console.ReadLine();
Console.Write("文件名:");
string filename = Console.ReadLine();
Console.WriteLine("开始生成,请等待...");
new Program().Generate(namespaces, filename);
Console.WriteLine("生成成功...");
Console.ReadKey();
} /// <summary>
/// 生成Model文件
/// </summary>
/// <param name="namespaces"></param>
/// <param name="filename"></param>
private void Generate(string namespaces, string filename)
{
byte[] myByte = Encoding.UTF8.GetBytes(BuildTemplete(namespaces));
string filepath = Environment.CurrentDirectory + "\\" + filename;
if (File.Exists(filepath))
{
File.Delete(filepath);
}
using (FileStream fsWrite = new FileStream(filepath, FileMode.Append))
{
fsWrite.Write(myByte, , myByte.Length);
};
} /// <summary>
/// 创建模板
/// </summary>
/// <param name="namespaces"></param>
/// <returns></returns>
private string BuildTemplete(string namespaces)
{
StringBuilder templete = new StringBuilder("using System;");
templete.Append("using System.Collections.Generic;\n\n");
templete.AppendFormat("namespace {0}\n{{\n", namespaces);
List<TableModel> tables = GetTables();
foreach (var table in tables)
{
templete.AppendFormat(" #region {0}\n", table.name);
templete.Append(" /// <summary>\n");
templete.AppendFormat(" /// {0}模型\n", table.name);
templete.Append(" /// </summary>\n");
templete.Append(" [Serializable]\n");
templete.AppendFormat(" public class {0} : BaseModel\n {{", table.name);
templete.Append("\n");
templete.Append(" /// <summary>\n");
templete.Append(" /// 表名\n");
templete.Append(" /// </summary>\n");
templete.AppendFormat(" public static readonly string TableName = \"{0}\";\n", table.name);
templete.Append("\n");
templete.Append(" /// <summary>\n");
templete.Append(" /// 构造函数\n");
templete.Append(" /// </summary>\n");
templete.AppendFormat(" public {0}() : base(TableName) {{ }}\n", table.name);
templete.Append(" private Guid Id = Guid.Empty;\n");
table.columns.ForEach(columu =>
{
templete.Append("\n");
templete.Append(" /// <summary>\n");
templete.AppendFormat(" /// {0}\n", columu.ColComment);
templete.Append(" /// </summary>\n");
if (columu.IsPk)
{
templete.AppendFormat(" public Guid {0}\n", columu.ColName);
templete.Append(" {\n");
templete.Append(" get { return Id; }\n");
templete.Append(" set\n");
templete.Append(" {\n");
templete.Append(" Id = value;\n");
templete.Append(" if (value != null)\n");
templete.Append(" {\n");
templete.Append(" base.BaseId = value;\n");
templete.Append(" }\n");
templete.Append(" }\n");
templete.Append(" }\n");
}
else
{
templete.AppendFormat(" public {0} {1} {{ get; set; }} {2}\n", GetCSType(columu.ColType), columu.ColName, GetCSDefault(columu.ColDefault));
}
});
templete.Append(" }"); templete.Append("\n"); templete.Append(" /// <summary>\n");
templete.AppendFormat(" /// {0}数据模型\n", table.name);
templete.Append(" /// </summary>\n");
templete.Append(" [Serializable]\n");
templete.AppendFormat(" public class {0}ListData\n {{", table.name);
templete.Append("\n");
templete.Append(" /// <summary>\n");
templete.Append(" /// 总记录数\n");
templete.Append(" /// </summary>\n");
templete.Append(" public int RecordCount { get; set; }\n");
templete.Append(" /// <summary>\n");
templete.Append("\n");
templete.Append(" /// 数据列表\n");
templete.Append(" /// </summary>\n");
templete.AppendFormat(" public List<{0}ListModel> RecordList {{ get; set; }}\n", table.name);
templete.Append(" }"); templete.Append("\n"); templete.Append(" /// <summary>\n");
templete.AppendFormat(" /// {0}列表模型\n", table.name);
templete.Append(" /// </summary>\n");
templete.Append(" [Serializable]\n");
templete.AppendFormat(" public class {0}ListModel\n {{", table.name);
templete.Append("\n");
table.columns.ForEach(columu =>
{
if (columu.ColName != "IsDeleted")
{
templete.Append("\n");
templete.Append(" /// <summary>\n");
templete.AppendFormat(" /// {0}\n", columu.ColComment);
templete.Append(" /// </summary>\n");
if (new string[] { "Guid", "DateTime" }.Contains(GetCSType(columu.ColType)))
{
templete.AppendFormat(" public string {0} {{ get; set; }}\n", columu.ColName);
}
else
{
templete.AppendFormat(" public {0} {1} {{ get; set; }}\n", GetCSType(columu.ColType), columu.ColName);
}
}
});
templete.Append(" }\n");
templete.Append(" #endregion\n");
templete.Append("\n");
}
templete = templete.Remove(templete.Length - , );
templete.Append("}");
return templete.ToString();
} /// <summary>
/// 获取表数据
/// </summary>
/// <returns></returns>
private List<TableModel> GetTables()
{
List<TableModel> tables = new List<TableModel>();
DataTable tabName = Query("SELECT name AS TableName FROM sysobjects WHERE xtype = 'U'");
DataTable colName = Query(@"--获取表名、字段名称、字段类型、字段说明、字段默认值
SELECT obj.name AS TableName,--表名
col.name AS ColName,--列名
typ.name AS ColType,--字段类型
cmt.value AS ColComment,--字段说明
dft.text AS ColDefault--字段默认值
FROM syscolumns col--字段
INNER JOIN sysobjects obj--表
ON col.id = obj.id
AND obj.xtype = 'U'--表示用户表
LEFT JOIN systypes typ--类型
ON col.xtype = typ.xusertype
LEFT JOIN sys.extended_properties cmt--字段说明
ON col.id = cmt.major_id--表Id
AND col.colid = cmt.minor_id--字段Id
LEFT JOIN syscomments dft--默认值
ON col.cdefault = dft.id
ORDER BY obj.name,
col.id ASC
");
DataTable pk = Query(@"--获取表的主键字段名
SELECT CCU.COLUMN_NAME,
TC.TABLE_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU
ON TC.CONSTRAINT_NAME = CCU.CONSTRAINT_NAME
WHERE TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
");
foreach (DataRow row in tabName.Rows)
{
TableModel table = new TableModel();
table.name = row["TableName"].ToString(); ;
table.columns = new List<ColumnModel>();
DataRow[] cols = colName.Select(string.Format("TableName = '{0}'", row["TableName"].ToString()));
DataRow[] pks = pk.Select(string.Format("TABLE_NAME = '{0}'", row["TableName"].ToString()));
string primarykey = pks == null || pks.Length == ? "" : pks[]["COLUMN_NAME"].ToString();
foreach (DataRow col in cols)
{
ColumnModel column = new ColumnModel();
column.IsPk = primarykey == col["ColName"].ToString();
column.ColName = col["ColName"].ToString();
column.ColType = col["ColType"].ToString();
column.ColComment = col["ColComment"].ToString();
column.ColDefault = col["ColDefault"].ToString();
table.columns.Add(column);
}
tables.Add(table);
}
return tables; } /// <summary>
/// 简单的SQL查询
/// </summary>
/// <param name="sqlString"></param>
/// <returns></returns>
private DataTable Query(string sqlString)
{
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(_connstr))
{
using (SqlCommand command = conn.CreateCommand())
{
command.CommandText = sqlString;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = command;
adapter.Fill(dt);
}
}
return dt;
} /// <summary>
/// 获取C#类型
/// </summary>
/// <param name="sqlType"></param>
/// <returns></returns>
private string GetCSType(string sqlType)
{
switch (sqlType)
{
case "datetime":
return "DateTime";
case "int":
return "int";
case "nchar":
return "string";
case "nvarchar":
return "string";
case "varchar":
return "string";
case "text":
return "string";
case "ntext":
return "string";
case "uniqueidentifier":
return "Guid";
case "decimal":
return "decimal";
case "float":
return "float";
case "bit":
return "byte";
case "binary":
return "byte []";
case "varbinary":
return "byte []";
case "timestamp":
return "int";
default:
return "";
}
} /// <summary>
/// 获取C#默认值
/// </summary>
/// <param name="sqlValue"></param>
/// <returns></returns>
private string GetCSDefault(string sqlValue)
{
switch (sqlValue)
{
case "((0))":
return "= 0;";
case "('')":
return "= string.Empty;";
case "('00000000-0000-0000-0000-000000000000')":
return "= Guid.Empty;";
default:
return "";
}
}
} /// <summary>
/// 表模型
/// </summary>
public class TableModel
{
/// <summary>
/// 表名
/// </summary>
public string name { get; set; } /// <summary>
/// 表字段
/// </summary>
public List<ColumnModel> columns { get; set; }
} /// <summary>
/// 字段模型
/// </summary>
public class ColumnModel
{
/// <summary>
/// 是否主键
/// </summary>
public bool IsPk { get; set; } /// <summary>
/// 列名
/// </summary>
public string ColName { get; set; } /// <summary>
/// 列类型
/// </summary>
public string ColType { get; set; } /// <summary>
/// 列说明
/// </summary>
public string ColComment { get; set; } /// <summary>
/// 列默认值
/// </summary>
public string ColDefault { get; set; }
}
}

C#:CodeSmith根据数据库中的表创建C#数据模型Model + 因为没有钱买正版,所以附加自己写的小代码的更多相关文章

  1. 用SQL语句创建和删除Access数据库中的表;添加列和删除列

    用SQL语句创建和删除Access数据库中的表;添加列和删除列 Posted on 2009-08-11 13:42 yunbo 阅读(1240) 评论(0) 编辑 收藏 用SQL语句创建和删除Acc ...

  2. 分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)

    分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间) 很多时候我们都需要计算数据库中各个表的数据量和每行记录所占用空间 这里共享一个脚本 CREATE TABLE #tab ...

  3. 清空SQL Server数据库中所有表数据的方法(转)

    清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入 ...

  4. 通过jdbc获取数据库中的表结构

    通过jdbc获取数据库中的表结构 主键 各个表字段类型及应用生成实体类   1.JDBC中通过MetaData来获取具体的表的相关信息.可以查询数据库中的有哪些表,表有哪些字段,字段的属性等等.Met ...

  5. 利用SQL语句查询数据库中所有表

    Oracle: SELECT * FROM ALL_TABLES;系统里有权限的表 SELECT * FROM DBA_TABLES; 系统表 SELECT * FROM USER_TABLES; 当 ...

  6. python生成数据库中所有表的DESC描述

    在数据库设计完成之后, 常常需要在 wiki 或其他文档中保存一份数据库中所有表的 desc 描述, 尤其是每个字段的含义和用途. 手动去生成自然是不可取的. 因此, 我编写了一个简单的 python ...

  7. (转)分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)

    分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间) 很多时候我们都需要计算数据库中各个表的数据量和每行记录所占用空间 这里共享一个脚本 CREATE TABLE #tab ...

  8. 【Sqlserver清空数据库中所有表数据】

    脚本: CREATE PROCEDURE sp_DeleteAllData AS EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT AL ...

  9. 清空SQL Server数据库中所有表数据的方法

    原文:清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可 ...

随机推荐

  1. express使用session会话

    前几周在学习nodejs基础,发现nodejs没有session会话变量,导致登录注册实现多了很多步骤.现在记录一下express中会话变量用法 安装express-session方法: 1.cnpm ...

  2. 黑马MyBatisday2 MyBatis Dao层实现 接口代理实现&传统实现 动态SQL和SQL抽取 自定义类型处理 分页插件PageHelper

    package com.itheima.mapper; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelp ...

  3. poj3728The merchant树剖+线段树

    如果直接在一条直线上,那么就建线段树 考虑每一个区间维护最小值和最大值和答案,就符合了合并的条件,一个log轻松做 那么在树上只要套一个树剖就搞定了,多一个log也不是问题 注意考虑在树上的话每一条链 ...

  4. 丝滑顺畅:使用CSS3获取60FPS动画

    原文链接: Smooth as Butter: Achieving 60 FPS Animations with CSS3 在移动端使用动画元素是很容易的. 如果你能遵循我们的这里的提示, 在移动端适 ...

  5. Net Core迁移到MSBuild

    Net Core迁移到MSBuild平台(二)   阅读目录 一.前言 二.XML定义 三.结语 回到目录 一.前言 在上一篇文章.Net Core迁移到MSBuild的多平台编译问题中,简单的讲了下 ...

  6. 渣渣菜鸡的 ElasticSearch 源码解析 —— 环境搭建

    关注我 转载请务必注明原创地址为:http://www.54tianzhisheng.cn/2018/08/25/es-code01/ 软件环境 1.Intellij Idea:2018.2版本 2. ...

  7. 洛谷 P1690 贪婪的Copy

    题目 本题难度较低,操作比较简单,首先对于范围较小的N(<=100),我们可以先跑一遍floyd,求出任意两点之间的最短路.对于很小的p(<=15),我们可以直接考虑全排列,运用到next ...

  8. 洛谷P2606 [ZJOI2010]排列计数(组合数 dp)

    题意 题目链接 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案 ...

  9. JavaScript笔记5-事件

    一.概述: 事件是可以被JavaScript侦测到的行为.网页中的每个元素都可以产生某些可以触发JavaScript函数的事件.相当于让标签在满足某种条件的时候,调用指定的方法. 二.常用事件 1:o ...

  10. 3D图形引擎决定三维产业差异化

    从2009年中国3D产业初步兴起开始,短短几年间中国的3D技术得到了飞速的发展,3D打印机.3D投影仪.Web3D.虚拟现实.场景漫游等等产业应用应运而生,设备制造商和内容提供商都开始发挥自主创新的优 ...