您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
C# 代码生成器 & 网站架构设计
 
作者:WizardWu 来源:博客园 发布于 2015-6-12
   次浏览      
 

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

本帖的示例下载点:http://files.cnblogs.com/WizardWu/091216.zip

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

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

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

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

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

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

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

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

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

genDataSet()
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 }

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

Model 实例层
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 展示层
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 商业逻辑层
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 数据访问层
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 语句,以利于中大型系统日后的维护。其内容非三言两语可道尽,本文不再深入探讨。

   
次浏览       
相关文章

企业架构、TOGAF与ArchiMate概览
架构师之路-如何做好业务建模?
大型网站电商网站架构案例和技术架构的示例
完整的Archimate视点指南(包括示例)
相关文档

数据中台技术架构方法论与实践
适用ArchiMate、EA 和 iSpace进行企业架构建模
Zachman企业架构框架简介
企业架构让SOA落地
相关课程

云平台与微服务架构设计
中台战略、中台建设与数字商业
亿级用户高并发、高可用系统架构
高可用分布式架构设计与实践
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]

专家视角看IT与架构
软件架构设计
面向服务体系架构和业务组件
人人网移动开发架构
架构腐化之谜
谈平台即服务PaaS

面向应用的架构设计实践
单元测试+重构+设计模式
软件架构师—高级实践
软件架构设计方法、案例与实践
嵌入式软件架构设计—高级实践
SOA体系结构实践

锐安科技 软件架构设计方法
成都 嵌入式软件架构设计
上海汽车 嵌入式软件架构设计
北京 软件架构设计
上海 软件架构设计案例与实践
北京 架构设计方法案例与实践
深圳 架构设计方法案例与实践
嵌入式软件架构设计—高级实践
更多...