NToggery 开发之旅(01) – 程序架构

NToggery 开发之旅(01) – 程序架构

 

项目名称:NToggery

项目简介:服装进销存基础平台

程序版本:2.2.61111

作者:Clark Chan

博客:http://clarkchan.cnblogs.com/

邮箱:taeheesoft#163.com

运行环境:Microsoft Visual Studio 2005Microsoft SQL Server 2000

NToggery名称含义:N多服装店都选用的,基于.NET Framework的服装进销存基础平台。(N多,就是很多的意思)。

 

引言:

首先祝单身的朋友,节日快乐!最近园子里的热门话题是开源软件。我以前也打算做一个开源项目,让大家的智慧聚焦在项目上,产生头脑风暴。最近仔细学习了几个开源的例子后,觉得:

1,我的代码还没有达到开源软件的实力。(代码无实力)

2,我自己还不具备完整的开源基础知识。(开源知识基础差)

3,我也没有良好的开源软件的环境和条件。(开源的方式不明)

如果我做开源软件,却不能满足她的标准。项目质量就难以保证。综合很多客观因素,决定暂时放弃开源软件的做法(等聚集一些实力后,再做成开源软件)。现在通过NToggery开发之旅的方式,提供一个平台,公开源代码和设计思路。和大家一起学习,共同积累。请大家多多指教,欢迎提出Bug和建议。

 

正文:

现在通过一个Sample说明NToggery商业需求的解决方案思路:1、  NToggery2数据库中的表结构:

数据库中有一张表“Staff”:

PrimaryKey

StaffId

int

4

Not NULL

 

StaffName

varchar

50

Not NULL

 

另外一张表“Demo”:

PrimaryKey

DemoId

int

4

Not NULL

 

DemoName

varchar

50

Not NULL

 

ListPrice

decimal

9

 

 

Quantity

int

4

Not NULL

ForeignKey

CreatedStaffId

int

4

Not NULL

 

CreatedDate

datetime

8

Not NULL

ForeignKey

ModifiedStaffId

int

4

Not NULL

 

ModifiedDate

datetime

8

Not NULL

 

IsValid

bit

1

Not NULL

 

很明显这里的关系是:Demo表中的CreatedStaffIdModifiedStaffId字段的值来自Staff表中的StaffId

还有一个关系就是Demo表中有一个唯一性约束IX_Demo:表示DemoName字段不能重复。

 

2、  现在我们来定义Demo表的数据商业规则以及数据访问的SQL逻辑:

 

(1)       添加的时候:

DemoId为表中最大数加一,由存储过程dbo.usp_NewId得到。日期字段ModifiedDate = CreatedDate取自服务器的时间getdate()方法,即修改时间等于创建时间。ModifiedStaffId = CreatedStaffId 取自界面的输入,即修改人等于创建人。DemoNameListPriceQuantity取自界面的输入。IsValid=1代表插入的记录有效

 

所以添加的时候,输入参数只有4个(@DemoName,@ListPrice,@Quantity,@CreatedStaffId)。在这里我采用存储过程进行Insert(参见存储过程:dbo.usp_Demo_Insert

 

(2)       删除的时候:

我们商业要求是不能物理删除记录,老板需要查看什么人在什么时候,删除了哪条记录。DemoId取自界面的输入。这里我们的方法是用Update语句将IsValid 写为0,代表该记录已经删除。删除的时候应该要记录删除人,这里我遗漏了,sorry,只能下次修改了。删除时间应该写在字段ModifiedDate=getdate()

 

所以删除的时候,输入的参数应该有2个(@DemoId@ModifiedStaffId漏掉了sorry~~)。

在这里我采用存储过程dbo.usp_Demo_Delete

 

(3)       修改的时候:

取自界面的字段是:DemoIdDemoNameListPriceQuantityModifiedStaffId。修改时间ModifiedDate=getdate()。这里要提一下:由于Demo表中有一个唯一性约束IX_Demo,所以我们在添加,和修改的存储过程中可以添加效验判断,排除添加重复的DemoName

 

所以修改的时候,输入的参数应该有5个(@DemoId,@DemoName,@ListPrice,@Quantity,@ModifiedStaffId)。这里我采用存储过程dbo.usp_Demo_Update

 

(4)       查询的时候:

通常查询的时候我们有2种商业需求。查询主键的那条记录和以一定的条件查询多条记录。在这里我用了2个存储过程去实现:dbo.usp_Demo_SelectOnedbo.usp_Demo_SelectAll

我们把它称为查看一条记录(View)和查询多条记录(Query)

 

所以View的时候,输入的参数只有1个(@DemoId)。

 

Query的时候可以有有限的多个参数:(@DemoId, @DemoName, @ListPrice, @Quantity, @CreatedStaffId, @CreatedDate,  @CreatedDateBegin, @CreatedDateEnd, @ModifiedStaffId, @ModifiedDate, @ModifiedDateBegin, @ModifiedDateEnd, @IsValid, @CreatedStaffName, @ModifiedStaffName)注意上面4个紫罗兰颜色的参数,是多余的,用来区间查询时间的,可以不要。(如:查询创建时间大于等于2006-10-1,小于2006-10-31的记录)关于存储过程dbo.usp_Demo_SelectAll的详细解释大家可以参考随笔http://www.cnblogs.com/ClarkChan/archive/2006/10/18/532565.html

 

(5)       关于多表关联的查询:

商业需求上,用户在界面能看到的只能是员工名称StaffName,老板不能理解1=“张三”,2=“李四”。于是查询SQL语句是:

SELECT a.DemoId, a.DemoName, a.ListPrice, a.Quantity, a.CreatedStaffId

 ,a.CreatedDate, a.ModifiedStaffId, a.ModifiedDate, a.IsValid

 ,b.StaffName AS CreatedStaffName

 ,c.StaffName AS ModifiedStaffName

 FROM Demo a

 LEFT OUTER JOIN Staff b ON a.CreatedStaffId = b.StaffId

 LEFT OUTER JOIN Staff c ON a.ModifiedStaffId = c.StaffId

在存储过程dbo.usp_Demo_SelectOnedbo.usp_Demo_SelectAll中都可以看到。

 

 

3、  至此5个存储过程就完成了,她们能解决一个特定的商业逻辑需求了。这里通过存储过程将SQL语句封装有几个好处:第一,她封装了部分不需要给程序处理的字段如:ModifiedDate=getdate(),等。第二,将SQL语句变成存储过程,可以自定义查询关联表,灵活的修改。如:添加的时候定义有效IsValid=1。第三,程序变的简单,每个方法的作用就是执行一个存储过程,相当于存储过程的数据访问方法的映射。如:SQLServerDAL中的5个方法

public void Insert(DemoModel demoModel)

public void Delete(DemoModel demoModel)

public void Update(DemoModel demoModel)

public DemoModel SelectOne(DemoModel demoModel)

public IList<DemoModel> SelectAll(DemoModel demoModel)

第四,其他好处就不多说了,就是存储过程的优点(MS上面说的)。当然存储过程有有缺点,这里要用的是她的优点,缺点就不讨论了。

 

4、  现在我们讲讲辅助代码生成工具的原理,及视图作用解释:

CodingBuilder(代码民工)v3.1,工作时候需要一个视图的支持dbo.uv_Demo

打开视图我们看到如下代码:

CREATE  view uv_Demo

as

SELECT a.DemoId, a.DemoName, a.ListPrice, a.Quantity, a.CreatedStaffId

 ,a.CreatedDate, a.ModifiedStaffId, a.ModifiedDate, a.IsValid

 ,b.StaffName AS CreatedStaffName

 ,c.StaffName AS ModifiedStaffName

 ,convert(datetime, '19000101',112) AS CreatedDateBegin

 ,convert(datetime, '19000101',112) AS CreatedDateEnd

 ,convert(datetime, '19000101',112) AS ModifiedDateBegin

 ,convert(datetime, '19000101',112) AS ModifiedDateEnd

 FROM Demo a

 LEFT OUTER JOIN Staff b ON a.CreatedStaffId = b.StaffId

 LEFT OUTER JOIN Staff c ON a.ModifiedStaffId = c.StaffId

 

WHERE a.IsValid = 1

其实她就是查询的时候的那段多表联接的SQL语句(也就是说多写这个视图,对于你的工作量,基本没有增加~:)。利用这个联接后的SQL语句,CodingBuilder能得到一个实体类DemoModel.cs,她以上面视图中的所有字段作为其属性。其中也多了4个特别的字段用来查询区间日期的,可以不要!(无此商业需求的时候,可以不写)。

 

5、  有了上面的实体类DemoModel.cs,我们也能很轻松的定义出接口类:IDemo.cs。那么现在的复杂问题就落在SQLServerDAL数据访问层的类:Demo.cs了。这个类其实就是数据库中存储过程的方法映射,她由5个存储过程,映射5个方法。方法的参数是实体DemoModel.cs。具体5个操作数据库的方法会使用那个实体的属性,决定于存储过程的参数。所以不难写出其方法,如Insert方法仅仅使用了4个属性:

public void Insert(DemoModel demoModel)

{

string strSql = "dbo.usp_Demo_Insert";

SqlParameter[] parameters = new SqlParameter[4];

 

parameters[0] = new SqlParameter("@DemoName", SqlDbType.VarChar, 50);

parameters[0].Value = demoModel.DemoName;

 

parameters[1] = new SqlParameter("@ListPrice", SqlDbType.Decimal, 9);

parameters[1].Value = demoModel.ListPrice;

 

parameters[2] = new SqlParameter("@Quantity", SqlDbType.Int, 4);

parameters[2].Value = demoModel.Quantity;

 

parameters[3] = new SqlParameter("@CreatedStaffId", SqlDbType.Int, 4);

parameters[3].Value = demoModel.CreatedStaffId;

 

SqlHelper.ExecuteNonQuery(strSql, parameters);

}

。业务逻辑层BLL的类Demo.cs方法同上了。

根据前面的数据库逻辑铺垫,CodingBuilder可以完全生成ModelIDALSQLServerDALBLL

 

6、  问题与思考:

在上面可以知道我们只要做好了数据库,代码都能有程序生成了。无疑是个方便的事情,但是写存储过程变成了麻烦事了,嘿嘿。这个原因是商业需求的复杂,导致需要多表关联,需要日期取自服务器的getdate(),等等。但是,如果您的商业需求很简单的话,如通常的增、删、改、查,都只操作一张表的话,存储过程的作用似乎就渺小了。(在这种情况下写存储过程将变的无聊,其实这种简单逻辑的存储过程,也能由程序生成,所以您不需担心。因为程序最喜欢做简单、重复的劳动拉~~~~)。当然这个解决方案还有不少问题未解决,在以后和大家一起解决。

 

7、  如果大家有什么不明白的地方,看看数据库和源代码就能明白了。如果您懂PetShop4.0的架构,会发觉本程序很简单,甚至很肤浅。哈哈:)我只是抛砖引玉,希望带给咱菜鸟级(俺是菜鸟)的程序员有所思考和提高。更希望高手可以指点,让大家一起提高。另外不懂PetShop4.0的架构的朋友,在我的随笔里面也有相应的基础随笔,可供参考。欢迎大家对NToggery基础设计架构提出宝贵意见!

 

最后请大家多多指教,欢迎提出Bug和建议。谢谢!

 

 

2006/11/11 Clark Chan

 

 

 

声明:
任何人,不要向我索要CodingBuilder v3.1的源代码!(免得我苦难的开口拒绝)
我的目的是NToggery基础平台,一切行为都是为了保障NToggery的顺利开发,服务的。

CodingBuilder v3.1暂未列入开放源代码的计划!!在有空的时候,我会把AutoCode0.8和EntityCode2.0的源代码整理公开。CodingBuilder v3.1中使用到的相关原理,在有空的时候我也会整理成随笔公开,与大家共同学习。如:
SQL Server 2000 元数据应用(五)
SQL Server 2000 元数据应用(四)
SQL Server 2000 元数据应用(三)
SQL Server 2000 元数据应用(二)
SQL Server 2000 元数据应用(一)
【原创】【开源】利用事件-委托,实现主-子窗体动态显示,不同菜单栏,不同工具栏。

再比如NToggery中使用的方法:
Microsoft .NET Pet Shop 4.0 学习之旅(四) - 七层架构的源代码
【原创】【开源】通用查询存储过程,可应用于多表关联的动态条件查询。



源文件下载地址:https://files.cnblogs.com/ClarkChan/NToggery_v2.1.61111.rar(858 KB)
《文件结构说明》
辅助代码生成工具:
\\Tools\CodingBuilderSetup_v3.1.61111\CodingBuilderSetup.msi
相关的备份文件:
\\BACKUP\*.*
数据库文件:
\\Database\NToggery2_Data.MDF
\\Database\NToggery2_Log.LDF
源代码工程:
\\SourceCode\NToggery.sln
重要文档:
\\SourceCode\License.txt
\\SourceCode\ReadMe.txt
\\SourceCode\WhatsNew.txt

最后非常感谢博客园提供这样的平台供大家学习交流,感谢dudu以人为本的帮助,谢谢!!

注意!在博客园社区以外转载,必须注明:
作者:Clark Chan
和原文出处:http://clarkchan.cnblogs.com/
否则谢绝转载!


posted on 2006-11-11 18:31  Clark Chan  阅读(1726)  评论(2编辑  收藏  举报

导航