首页 > 编程语言 >C# 代码生成器 & 网站架构设计

C# 代码生成器 & 网站架构设计

时间:2022-12-02 16:02:43浏览次数:51  
标签:代码生成 Product 架构设计 C# dcInsertInput 项目名称 new Model com

自己写的一个 web 版简易 C# Code Generator,可快速产生某个数据库中,所有表 Mapping 的 C# 3.0 类。可当作网站分层开发、表单大量传递用户输入值、在内存里持久化保存值之用,亦可当作 NHibernate 等 O/R Mapping 框架套用时的 C# 代码生成器。

因敝人觉得 CodeSmith、MyGeneration 软件产生的类和代码太复杂,不见得符合自己所需,甚至市面上有些代码生成器还要收费,遂自己随手用 ASP.NET 写了一个代码生成器,并分享出来。功能尚简,以后有时间再继续扩充。

-------------------------------------------------

(执行本示例,需要 SQL Server 的 Northwind 数据库,以及 VS 2008 或 IIS)
-------------------------------------------------

双击 CodeGenerator.sln,开启网站后,如下图 1,下拉菜单中,会自动撷取网站 Web.config 中,一至多个数据库连接的字符串。

C# 代码生成器 & 网站架构设计_SQL


图 1 程序执行画面,用户可自定义要生成的 C# 类其部分内容


C# 代码生成器 & 网站架构设计_C#_02


图 2 程序会自动撷取 Web.config 中的一至多个数据库连接字符串


如下图 3,单击「列出此数据库的所有表」按钮后,会在 GridView 控件中,列出这个数据库的所有「表 (Table)」和「视图 (View)」。用户可逐一勾选,或全选要创建的表之后,再单击「开始创建」按钮即可。

C# 代码生成器 & 网站架构设计_C++_03


图 3 创建后的 C# 类,会自动产生在此网站  底下的 Entities 文件夹里


下图 4 为创建的 C# 类其内容。C# 的类型,会和数据库中的类型自动做对应,例如 string 对应 varchar、Int16 对应 smallint。当然您可视自己的需求,修改代码再扩充。

C# 代码生成器 & 网站架构设计_C#_04


图 4 创建的 C# 类其内容,用户可选择是否要加入 NHibernate 的 Attribute


本示例用了一个 ADO.NET 书上教的技巧,搭配 DataReader,在单一次的数据库 connection 中,一次就取回多句 SQL 语句,所要撷取的多个 ResultSet (此为多行多列的二维类型数据), 以提升程序性能,如下方代码所示:

 

genDataSet()

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> 1 using (SqlConnection conn = new SqlConnection(strConnString))
2 {
3 conn.Open();
4 using (SqlCommand cmd = new SqlCommand())
5 {
6 cmd.Connection = conn;
7 cmd.CommandText = strSql;
8 using (SqlDataReader dr = cmd.ExecuteReader())
9 {
10 // 多次颉取 ResultSet (多行多列的二维类型数据)
11 for ( int ii = 0 ; ii < intDataTableCount; ii ++ )
12 {
13 dtInsertInput = new DataTable();
14
15 dcInsertInput = new DataColumn();
16 dcInsertInput.DataType = Type.GetType( " System.String " );
17 dcInsertInput.ColumnName = " TableName " ;
18 dtInsertInput.Columns.Add(dcInsertInput);
19
20 dcInsertInput = new DataColumn();
21 dcInsertInput.DataType = Type.GetType( " System.String " );
22 dcInsertInput.ColumnName = " ColumnName " ;
23 dtInsertInput.Columns.Add(dcInsertInput);
24
25 dcInsertInput = new DataColumn();
26 dcInsertInput.DataType = Type.GetType( " System.String " );
27 dcInsertInput.ColumnName = " DataType " ;
28 dtInsertInput.Columns.Add(dcInsertInput);
29
30 while (dr.Read())
31 {
32 drInsertInput = dtInsertInput.NewRow();
33 drInsertInput[ " TableName " ] = dr.GetString( 1 );
34 drInsertInput[ " ColumnName " ] = dr.GetString( 2 );
35 drInsertInput[ " DataType " ] = dr.GetString( 6 );
36 dtInsertInput.Rows.Add(drInsertInput);
37 // Response.Write(dr.GetString(1) + ", " + dr.GetString(2).ToString() + ", " + dr.GetString(6).ToString() + "<br>");
38 }
39
40 // 将这一次撷取的 ResultSet,存入一个新的 DataTable 后,再把这一个 DataTable 存入 DataSet 里
41 ds.Tables.Add(dtInsertInput);
42
43 // dtInsertInput.Clear();
44
45 dr.NextResult(); // 到 DataReader 的下一个 ResultSet 继续读取数据
46
47 Label1.Text += " 已经创建了第 " + ds.Tables.Count + " 个类<br> " ;
48 }
49 }
50
51 dcInsertInput.Dispose();
52 dtInsertInput.Dispose();
53 }
54 }
55


 

有关此 ADO.NET 的小技巧,有兴趣的网友可参考这篇文章:

使用 ADO.NET 的 NextResult 方法取得多个 Result Set

有些网站系统的设计,会采用「分层式; 多层式 (n-Tier)」的架构,如下图 5 所示。在 Layer 与 Layer 之间的数据传递,或电子表单中用户所输入的多个字段值的传递,亦可透过此种 Mapping 映射类的 instance,来帮忙传递大量的数据;还有些 Java/J2EE 的书中会提到,可再将这些数据暂存在内存中,以做一些「持久性 (persistence)」的延伸应用,这些暂存在内存里的 class 的多个字段值,以后随时可从内存中取出再使用。

 

C# 代码生成器 & 网站架构设计_SQL_05


图 5 分层的网站系统,透过 Model 实例层、C# 实例 (instance),帮忙传递用户在表单中输入的大量数据

 Model 实例层

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->namespace com.公司名称.项目名称.Model
{
public class Product //此一「类」的名称,会对应至数据库的同名「数据表」Product
{
private int _id; //此为 .NET 的「字段(field)」,对应至 Product 表的同名「字段」ID
private string _name;
private decimal _price;
public int ID          //此为 .NET 的「属性(property)」,对应至 Product 表的同名「字段」ID
{
set { _id = value; }
get { return _id; }
}
public decimal Price
{
set { _price = value; }
get { return _price; }
}

public string Name
{
set { _name = value; }
get { return _name; }
}
}
}

 

View 展示层

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> public partial class _Default : System.Web.UI.Page
{
// 用户单击 submit 送出按钮,欲「添加」一笔记录到数据库的 Product 表
protected void Button1_Click( object sender, EventArgs e)
{
com.公司名称.项目名称.Model.Product model = new com.公司名称.项目名称.Model.Product(); // 一个 Model 实例层的对象

com.公司名称.项目名称.BLL.Product bll = new com.公司名称.项目名称.BLL.Product(); // 一个 BLL 层的对象

model.ID = TextBox1.Text; // 将用户在表单中,所输入的 ID 数据,存储(set) 至 Model 实例层的对象
model.Name = TextBox2.Text; // 将用户在表单中,所输入的 Name 数据,存储(set) 至 Model 实例层的对象
model.Price = TextBox3.Text; // 将用户在表单中,所输入的 Price 数据,存储(set) 至 Model 实例层的对象

bll.executeInsert(model); // 将包装好的用户输入数据的集合,传递至 BLL 商业逻辑层
}
}

 

BLL 商业逻辑层

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> namespace com.公司名称.项目名称.BLL
{
public class Product
{
// 一个 DAL 数据访问层的对象
private com.公司名称.项目名称.DAL.Product dal = new com.公司名称.项目名称.DAL.Product();

public int executeInsert(com.公司名称.项目名称.Model.Product model)
{
//这里可以加入其他的商业逻辑


// 将包装好的用户输入数据的集合,传递至 DAL 数据访问层
return dal.executeInsert(model);
}
}
}

 

DAL 数据访问层

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->namespace com.公司名称.项目名称.DAL
{
public class Product
{
public int executeInsert(com.公司名称.项目名称.Model.Product model)
{
StringBuilder strSql = new StringBuilder();

//在这里组合出完整的 SQL 语句
strSql.Append("INSERT INTO Product(ID, Name, Price) VALUES (@ID, @Name, @Price)");

//ADO.NET 中的 SqlParameterCollection 类的应用,表单中所有输入数据的集合
System.Data.SqlClient.SqlParameter[] params = {
new SqlParameter("@ID", SqlDbType.Int),
new SqlParameter("@Name", SqlDbType.NVarchar, 30),
new SqlParameter("@Price", SqlDbType.Decimal) };

//在这将用户在表单中输入的多个数据,逐一填入 SQL 语句里的「参数(parameters)」
params[0].Value = model.ID;
params[1].Value = model.Name;
params[2].Value = model.Price;
//将组合好的整句 SQL 语句,透过共用的「DBUtility 数据库访问类」DbHelper,抛入数据库去执行「添加」的动作
com.公司名称.项目名称.DBUtility.DbHelper dbh;
int intResult = dbh.executeInsert(strSql.ToString(), params);


return intResult;
}
}
}


 

当然,若您只是单纯要传递用户在表单中输入的多个值,并非一定要透过此种 Mapping 的 C# 类 instance,微软 ADO.NET 提供的 SqlParameterCollection 类也很好用,且可事先设置好对应的数据表里,字段的类型和长度,如上方 DAL 数据访问层里的代码。

 

若真正要谈到 O/R Mapping 的议题,其特性及优点甚多,例如可避免在代码中,直接写死特定的数据表字段名称,或避免在前端代码中出现 SQL 语句,以利于中大型系统日后的维护。其内容非三言两语可道尽,本文不再深入探讨。

标签:代码生成,Product,架构设计,C#,dcInsertInput,项目名称,new,Model,com
From: https://blog.51cto.com/u_15834343/5907110

相关文章

  • CS应用程序开发中的异常处理
      我们在进行网络应用程序开发时(主要是CS架构的应用程序)要面对很多异常情况的处理,这些异常中有些是服务器端主动抛出的异常,客户端要按照事先约定好的规则分类处理;有些......
  • Oracle PL/SQL之对象权限与系统权限的撤销差异
    对象权限测试:  初始状态下,user2和user3都没有user1.t1的对象权限  user1下存在t1表:  duzz$user1@orcl>select * from t1;            C1  --------......
  • BizTalk 开发系列(四十) BizTalk WCF-SQL Adapter读取SQL Service Broker消息
    SQLServiceBroker是在SQLServer2005中新增的功能。ServiceBroker为SQLServer提供队列和可靠的消息传递,可以可用来建立以异步消息为基础的应用。当然从题目大家可......
  • vulfocus redis 未授权访问 (CNVD-2015-07557)
    一、简介1.Redis是一套开源的使用ANSIC编写、支持网络、可基于内存亦可持久化的日志型、键值存储数据库,并提供多种语言的API。2.Redis默认端口:6379,如果在没有开启认证的......
  • c++数据结构之vector
    文章目录​​1.关于vector​​​​2.定义、初始化​​​​3.插入元素​​​​4.删除元素​​​​5.遍历元素​​​​6.翻转和排序​​​​7.注意问题​​​​7.1删除元素​......
  • ReactHook父组件调用子组件的方法,且子组件用了connect
    ReactHook父组件调用子组件的方法,且子组件用了connect子组件1、引入useImperativeHandle,forwardRef2、子组件由function改成let,接收prop和ref,并从props中结构出refI......
  • 微服务之分布式搜索引擎elasticsearchDSL查询功能
    DSLQuery的分类Elasticsearch提供了基于JSON的DSL(DomainSpecific Language)来定义查询。常见的查询类型包括:查询所有:查询出所有数据,一般测试用。例如:match_all全文检......
  • ubuntu18.04下cmake的安装
    一.使用安装命令sudoaptinstallcmake这种方式安装最为简单,但是,这种方式安装的不是最新版本的Cmake。我此次安装cmake是因为要编译fastdds,其实之前系统中有cmake,但......
  • react18中useCallback与memo使用
     1、父组件Demo3Count组件缓存有两种方法a、  b、    2、子组件    3、效果3.1、初始均渲染  3.2、点击b......
  • Macbook 录屏幕
    记得之前用的Macbook自带的录屏挺好用的如何在Mac上录制屏幕-官方Apple支持(中国)如何在Mac上录制屏幕你可以使用“截屏”或QuickTimePlayer来录制显示整......