UML软件工程组织

基于 dot Net 的通用快速软件开发框架(NGSDF)
作者:Forceland 原创
 

在 dot Net应用开发中,如何利用对象的概念,方便、快速、灵活地创建稳定的软件系统,是许多软件开发公司的目标,本文基于一个通用的 dot Net开发框架——Class Engine,简要阐述对象技术的使用,以及Class如何与界面结合,组成整个软件开发流程,下面简称此框架为NGSDF,要了解更多的信息,请发Email至(jiangjian2002_cn@sina.com

 

l         前言

l         Class Engine的体系结构

l         Class Engine 的特性

l         Class Engine 的使用

l         O/R 映射定义

l         Class Engine 在ASP.Net开发中的应用

l         由NGSDF实现零代码开发

l         NGSDF提供的其他功能

l         总结

 

 

一、前言

  随着 dot Net 技术的推广,越来越多的公司正在向 dot Net 转型,采用 dot Net 开发系统,但是如何方便、快速、灵活地创建稳定的软件系统,是许多软件开发公司追求的目标。为实现这个梦想,通用的 dot Net开发框架——Class Engine孕育而生。设计人员可以专注于部件的功能设计,也就是Class的定义 。

 

二、Class Engine 的体系结构

Class Engine 被设计成由客户端来管理对象状态,持久化管理器(DataObjectManager,负责持久化对象获取、创建、更新、删除)不管理持久化对象的状态,也就是说不存在一个"容器"来保存所有管理器创建的对象,而是根据客户端的请求进行对象的获取、创建、更新、删除等操作。这使得开发者只需要定义一个可序列化的实体对象,即可实现分布式应用的对象持久化。

 

Class Engine 客户/服务器模式 O/R Mapping

 

 

 

Class Engine考虑在Microsoft Windows平台下分布式应用存在不同的应用模式,典型的如Entity-Collection-Class模式(简称为ECC模式),这些构架模式代表了整个应用的结构,它根据不同的应用特征变化。Class Engine不期望提供一个通用的分布式应用的构架模式,而是允许在Class Engine持久化框架的核心服务上扩展不同的应用模式来满足系统的要求。

 

基于Class Engine的应用框架

 

 

 

 

 

三、Class Engine 的特性

1、支持的数据源

Class Engine仅支持数据源为关系型数据库的对象持久化,目标数据库需要提供相应的Microsoft .Net Data Provider引擎,支持的数据库包括Oracle, Sybase, SQLServer, DB2, Access, Dabase, Foxpro, VFP

2、映射定义

Class Engine目前支持的映射配置

  • 代码文档属性元数据定义。利用映射属性类在持久化类或类的属性定义。

3、事务支持

Class Engine本身并不管理事务,但当在事务环境中时,支持事务的完成标志(Complete)和异常时取消(Abort)。

4、其他特性

  • 基于客户/服务器模式的框架。
  • 自动属性类型匹配。对象属性与字段映射时不需要定义数据类型,简化了映射的定义。
  • 支持持久化对象的关联。允许建立不同持久化对象之间的关联,定义关联多重性(一对一、一对多)。
  • 事务支持。Class Engine本身并不管理事务,但提供对事务的控制(同意或取消事务)。

当前Class Engine还不支持"懒装载"(Lazy Loading)或"按需装载"(On-Demand Loading)。

 

四、Class Engine 使用

1、定义一个持久化类

持久化类实际上是一个定义了属性(Property)或字段(Field)的类,因此持久化类的定义非常简单,但持久化类不能是抽象类并且需要有一个无参数的public的构造化函数。

字段或属性只有被定义为持久化属性时才会进行持久化,持久化属性的数据类型必须定义为:

  • .Net框架的基本类型
  • Byte数组(二进制数据)
  • 实现System.Collections.IList的类
  • 其它持久化类(对象关联时)

下面是一个简单的持久化类"Customer"的定义:

[C#] 
public class Customer
{
  //必须定义无参数的构造函数
  public Customer()
  {
  }
 
  public string Id { get; set; }
  public string Name {get; set; }
  public string Phone {get; set; }
}
                       

持久化类的映射配置可以使用属性在类上定义。类映射必须定义至少一个主键。有关对象映射配置的定义参见O/R映射定义

Customer类的采用属性进行映射配置的定义如下:

[C#] 
[ObjectMapping("customer","customer")] //定义映射的表名
public class Customer
{
  //必须定义无参数的构造函数
  public Customer()
  {
  }
 
  [PropertyMapping("id",true)] //定义对象属性映射的数据库字段,true表示本属性为主键
  public string Id { get; set; }
 
  [PropertyMapping("name")]
  public string Name {get; set; }
 
  [PropertyMapping("phone")]
  public string Phone {get; set; }
}
                       

   Class Engine并不定义属性映射的字段类型,Class Engine采用自动匹配的方式进行处理。.

2、管理持久化对象

持久化对象通过数据对象管理器(DataObjectManager)来进行访问。DataObjectManager提供了对象的获取、新增、更新和删除接口。

新增持久化对象实例

新增对象到持久存储中,首先必须创建一个新持久化对象实例,然后利用DataObjectManager接口将新对象保存到持久存储中

下面的示例简单演示了一个创建新Customer对象到持久存储中:

[C#] 
Customer customer = new Customer(); //创建持久化对象实例
customer.Id = "0001"; //设置对象属性
customer.Name = "john";
customer.Phone = "555-55555";
customer.Complete(); //保存到持久化存储中
                       

获取持久化对象实例

持久化对象实例必须通过对象的主键获取,如果主键只有一个属性,则可以直接利用属性定义的类型的对象;如果主键有多个属性,则需要定义一个主键对象来访问。

下面的示例简单演示了存在在持久存储中的Customer实例,因为Customer的主键只定义个一个属性:Id属性,因此可以直接用Id值获取对象实例:

[C#] 
//因为同一个DataObjectManager可以为多个持久化类服务,因此需要指定要返回的对象类型,这里通过
typeof(Customer)获得。
Customer customer = (Customer) DataObjectManager.Instance.GetObject(typeof(Customer),"0001");
                       

更新持久化对象实例

当一个持久化对象被修改后需要更新,已保存这种修改。

下面的示例演示了保存修改后的Customer实例:

[C#] 
//首先获得对象实例。这步不是必需的,也可以用new的方式创建新对象,但这个对象必须存在,否则将出错。
Customer customer = (Customer) DataObjectManager.Instance.GetObject(typeof(Customer),"0001"); 
customer.Name = "Will Smith"; //修改Name属性

customer.Complete(); //保存修改
                       

删除持久化对象

删除存在于持久化存储中的对象实例

下面的示例演示了删除Customer实例:

[C#] 
//首先获得对象实例。这步不是必需的,也可以用new的方式创建新对象,但这个对象必须存在,否则将出错。
Customer customer = (Customer) DataObjectManager.Instance.GetObject(typeof(Customer),"0001");
customer.Complete(); //删除对象
 

3、定义关联关系类

对象系统中,各个实体对象之间常常存在关系,它们需要相互协作,持久化类之间可以建立关联,用于定义父类与子类的关系称之为关联关系,用于代表子对象的类属性称为关联属性。关联关系必须在父类定义(RelationKeyMappingAttribute).

 

4、使用持久化控制接口

持久化管理器DataObjectManager支持IPersistenceControllable接口,实现IPersistentControllable接口持久化对象会被DataObjectManager的持久化操作回调,以提供持久化对象对持久化操作的控制。 IPersistenceControllable接口定义控制持久化操作新增、更新、删除、获取的接口。

下面的例子演示实现IPersistenceControllable接口的Student类利用BeforeNew接口在新增前检查是否有null值,并将null值设置为缺省置,以避免写入数据库时产生异常(表的字段被定义为不允许为空):

[C#] 
//学生类定义
[ObjectMapping("student")]
public class Student:IPersistenceControllable
{
  [PropertyMapping("student_id",true)]
  public int StudentId { get; set; }
  
  [PropertyMapping("name")]
  public string Name;
  
  [PropertyMapping("homeplace")]
  public string HomePlace; //学生的出生地,映射表不允许为空
  
  //实现IPersistenceControllable接口
  public void BeforeNew(){
    //在新增对象到持久化存储前检出对象数据的有效性
    if (Name == null || Name.Trim()=="") 
      throw new ArgumentNullException("Name不允许为空");
    if (HomePlace == null) HomePlace = "";
  }
  
  public void AfterNew(){};
  public void AfterLoad(){};
  public void BeforeUpdate(){};
  public void AfterUpdate(){};
  public void BeforeDelete(){};
  public void AfterDelete(){};
}
 
//下面的代码演示新增了实现IPersistentControllable接口的持久化对象
//首先创建一个新的学生
Student student = new Student();
student.Id = 2;
//未设置Name属性
//student.Name = "Mark";
 
//下面的代码出现异常,因为未设置Name属性
dom.NewObject(student); 
 
//下面的代码将不会出现异常,因为HomePlace在BeforeNew方法中设置了缺省值
student.Name  = "Mark";
student.Complete();
 
IPersistentControllable在事务环境中因为事务可能被回滚,但对IPersistentControllable的调用
不能回滚,因此不能在事务环境中使用IPersistentControllable接口来处理对持久化成功依赖的要求。 
 

5O/R映射定义

定义类映射

持久化类需要定义保存数据的表。对象映射定义映射的表名,属性与表字段的映射参见定义属性映射。

属性定义

ObjectMappingAttribute用于定义对象映射的表名,属性只能定义在类上。

下面例子演示了持久化类定义ObjectMapping属性:

[C#] 
[ObjectMapping("customer")] //Customer映射数据库的表"customer"
public class Customer
{
  //...
}
                       

持久化类也可定义数据源属性(DataSourceAttribute),该数据源仅用于该类,如下:

[C#] 
[ObjectMapping("customer")] //Customer映射数据库的表"customer"
[DataSource("accessdb","OleDb",@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb")]
 //定义用于Customer类的数据源
public class Customer
{
  //...
}

 

定义属性映射

持久化类通过属性映射定义类属性与表字段的映射。Class Engine并不要求定义属性的数据类型,持久化处理器自动进行数据类型的匹配。

属性定义

属性映射使用PropertyMappingAttribute进行设置,PropertyMappingAttribute只能定义在类的Field和Property上。

PropertyMappingAttribute可以设置以下属性:

属性

类型

描述

Field

System.String(.Net框架类型),string(c#)

映射表的字段名

IsPrimaryKey

System.Boolean(.Net框架类型),bool(c#)

是否主键。true表示该属性是主键属性

IsIdentity

System.Boolean(.Net框架类型),bool(c#)

是否自动赋值字段。某些数据库支持自动增长字段类型,在新增记录是不需要提供该字段的值,而由数据库自动设置。

DefaultValue

Sysem.Object(.Net框架类型), object(c#)

缺省值

下面的例子演示属性的映射定义:

[C#] 
[ObjectMapping("customer")]
public class Customer
{
  [PropertyMapping("id",true)] //映射表字段id,并且是对象主键
  public string CustomerId;
  
  [PropertyMapping("name")] //映射字段name
  public string Name;
  
  //映射字段valid,并且需要数字化布尔值的转换
  [PropertyMapping("valid",DataTransform = DataTransformFormat.NumbericBoolean)]
  public bool Valid;
}

定义关联

关联定义持久化对象之间的关系,在Class Engine中关联由父端和子端组成,父端和子端均可以定义关联对方的属性,可以通过关联属性来访问关联的对象。

定义父类和子类之间的关联,需要定义关联关系,关联键、和在持久化类的关联属性。

关联关系定义

关联定义持久化类与持久化类的关系,关系的定义端为父类,父类连接子类,子类也可以连接父类。持久化管理器在装载父类时将自动装载关联子类对象,但装载子类时则不会装载父类,则主要是为了避免循环装载。

关联关系定义包括关系的名称和父类、子类以及关联的键定义、关联表等关联信息。

RelationKeyMappingAttribute定义关联关系,一般定义在父类上,可以设置以下属性:

属性

类型

描述

childType

System. Type (.Net框架类型)

子类型。

primaryKey

System.String(.Net框架类型),string(c#)

父类主关键字。

relationKey

System.String(.Net框架类型),string(c#)

子类主关键字。

cascadeDelete

System.Boolean(.Net框架类型),bool(c#)

是否允许级联删除,即删除父对象时同时删除子对象。可选,默认为false

实体对象的状态管理

 

Class Engine库在进行持久化实体对象的管理操作时,依赖于对象的状态。为了管理对象的状态,实体类需要实现IPeristentObject接口,IPeristentObject提供了查询状态、设置状态的接口。

对象状态由类ObjectState定义,包括以下几种状态:

  • New:对象为新对象(未存在持久存储中)
  • Dirty:对象已被修改
  • Persisted:对象已持久化,即对象的数据与持久存储一致
  • Deleted:对象已被删除

实体对象可以通过State属性获得对象的状态。

除此之外,IPersistentObject还提供了一个用于标记预备删除的属性DeletionMark,当属性为true时表明对象请求从持久化存储中删除。

客户端维护的对象状态

为了支持客户/服务器方式的应用,Class Engine持久化管理器并不提供对象的状态管理,在Class Engine库中持久化管理器同样不提供对象的状态的管理,而由客户端负责维护其对象的状态,这意味着客户端调用管理器的Save接口后,客户端的实体类的状态并不会变为"Persisted",客户端必须通过调用IPersistent的Complete接口来同步状态。   

设计支持对象状态管理的实体类

对象正确的状态变化应当如下:

在一个对象被创建时对象的状态为"New";对象在保存后通过调用Complete接口同步对象的状态,此时对象的状态应当为"Persisted"或"Deleted"(DeletionMark为true);已保存的对象(状态为"Persisted")的持久化属性修改后,其对象状态应当为"Dirty"。

Class Engine中为了管理实体对象状态,实体类必须实现IPersistObject接口。Class Engine库提供了了实体类基类BasePersistentObject,该类已经实现了IPersistObject接口,因此可以直接从BasePersistentObject继承来产生自己的实体类。

正确地实现对象管理,实体类必须符合以下原则:

  • 新建的对象实例,初始状态必须为ObjectState.New(当实体类从PersistentObject继承时,其对象状态将自动为"New")。
·                      [C#] 
·                      Customer customer = new Customer();                                  
                                         
  • 修改了对象持久化属性后,应当设置对象为"脏"状态。IPersistentObject的MakeDirty接口设置属性为Dirty,当对象属性修改后应当利用该接口修改对象的状态。
·                      [C#] 
·                      //下面是Customer类定义,演示如何在对象持久化属性修改后,修改对象状态
·                      //(持久化类映射定义略)
·                      public class Customer
·                      {
·                        [PropertyMapping("id",true)]
·                        public string Id;
·                        
·                        private string name;
·                        [PropertyMapping("name")]
·                        public string Name
·                        {
·                          get { return name; }
·                          set { 
·                            name = value;
·                            //Name属性修改后,设置对象状态为"脏"
·                            this.MakeDirty("Name");
·                          }
·                        }
·                      }
                                         

持久化管理器处理对象状态的方式

要设置对象的删除标记,只需将DeletionMark设置为true,DeletionMark标记优先于State,Class Engine库的持久化管理器在进行Save操作,遵循以下原则(优先级从上到下):

  • DeletionMark为true,在执行Save时,如果State为"New",则持久化管理器不作处理,否则将从持久化存储中删除该实体对象。
  • State为"New",则新增该对象。
  • State为"Dirty",则更新该对象。

6、视图持久化定义

Class Engine 中,视图的持久化对象定义和普通表的定义相同,Class Engine支持视图更新

 

五、Class Engine 在ASP.Net开发中的应用

1、说明

Class Engine 较好的解决了应用程序数据的存储和逻辑的封装问题,可是现实开发中还需要实现表现层(UI),如何使Class Engine 与UI完美的结合是解决快速开发的又一大难题。下面简单介绍NGSDF体系结构及其。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2、开发步骤

在开发过程中,开发者只要专注于组件的定制,以及UI的配置(DataGrid的Columns和WayControlTable的Items)。NGSDF提供了快速组件生成工具和UI配置工具,使得整个开发效率加倍提高。

配置流程如下,假设开发者需要做一个员工信息维护模块:

在数据库中创建表(Employee)及其关联表

例如员工信息、民族,政治面貌,家庭成员等,并在应用程序项目中建立EmployeeForm.Aspx页面(页面的界面风格和CS代码可以利用NGSDF附带的例子),此页面的相应类必须继承Forceland.Web.AbstractPageBase,实际使用中可以建立一个PageBase类,用于继承Forceland.Web.AbstractPageBase作为桥接,之后只要继承PageBase类即可。

利用NGSDF “框架表信息”配置Employee数据

界面如下,通过“系统表和框架表数据匹配”,把Employee表的信息自动导入NGSDF框架表的TableItem 和 FieldItem表中, 通过点击Employee记录配置对应的字段信息

 

 

1、              

通过代码生成器自动产生Employee的类代码,

拷贝Employee类代码,并应用到项目中(记得在CS文件头加上using Forceland.DataMapping;)

通过列生成器自动产生UI界面

可以根据需要产生显示记录的DataGrid的Columns和显示详细信息用的WayControlTable 的Items

修改_CurrentEntryType = typeof(Employee)即可

这样就完成了整个Employee添加,删除,修改,导出,查询等功能,还有权限控制,

操作跟踪,非法输入验证等,代码页面如下

浏览EmployeeForm界面

配置好的EmployeeForm运行页面如下

3、业务逻辑的封装

考虑到实际项目应用的复杂性,框架预留了大量的控制接口,列表如下,都可以根据实际的开发需要来重载系统功能

登陆用户信息

//当前登陆用户信息,根据用户登陆时设置的HttpContext.Current.Session["AccountID"]值来设置LoginUser内容,可以重载此属性

protected virtual User LoginUser

//根据指定的用户ID和类型获取用户名称,具体实现由特定的系统决定

protected virtual string GetUserName(int uId,int uType)

持久化接口

          // 在将实体从数据库删除之后调用的接口。

          public virtual void AfterDelete()

          // 在准备将实体从数据库删除之前调用的接口。

          public virtual void BeforeDelete()

          // 在新实体创建到数据库之前被调用的接口。实现类可以在本方法实现持久属性的初始化。

          public virtual void BeforeNew()

          // 在新实体创建到数据库之后被调用的接口。

          public virtual void AfterNew()

          // 在准备将实体更新到数据库之前调用的接口。

          public virtual void BeforeUpdate()

          // 在将实体更新到数据库之后调用的接口。

          public virtual void AfterUpdate()

          // 在准备将实体更新到数据库之前调用的接口。

          protected virtual void BeforeSave()

          // 在将实体更新到数据库之后调用的接口。

          protected virtual void AfterSave()

          // 在将实体从数据库装载之后调用的接口。

          public virtual void AfterLoad()

          //  持久化对象被更新时触发

          protected virtual void Updateing(BasePersistentObject persistentObj)

          //  持久化对象被呈现时触发

          protected virtual void Showing(BasePersistentObject persistentObj)

          //  记录被选择之前触发

          protected virtual void BeforeGridSelecting()

          //  记录被选择之后触发

          protected virtual void AfterGridSelecting()

          //  按钮被点击之前触发的事件

          protected virtual void BeforeDoClick(object sender, System.EventArgs e)

          //  按钮被点击之后触发的事件

          protected virtual void AfterDoClick(object sender, System.EventArgs e)

          // 在准备将实体更新到数据库之前调用的接口。

          protected virtual void BeforeSave() {}

          // 在将实体更新到数据库之后调用的接口。

          protected virtual void AfterSave() {}

数据绑定方法

//   绑定数据到DataGrid,同时初始化Grid的选择列信息

protected virtual void bindDataGrid(WayDataGridPager pager,DataGrid grid)

///   得到需要绑定到 _CurrentDataGrid上的Sql语句,在Grid数据绑定时被调用,

///   可以重载此方法

protected virtual string GetBindDataGridSql()

初始信息设置

//  初始化基础信息

protected virtual void IniInformations()

//模板方法,封装所有页面的公共操作,在每个继承AbstractPageBase类及其子类的Page中都会被调用,   主要用来初始化一些基础数据,包括权限设置,安全检查

protected virtual void BaseTemplateMethod()

///   设置控件权限

protected virtual void BaseInitialzeControlEvent()

//数据库连接字符串,定义在Web.confg 的 "ConnString1",可以根据需要重载此属性

protected virtual string ConnectionString

//网格页数,定义在Web.confg 的 "PageSize",可以根据需要重载此属性

protected virtual int _GridPageSize

 

///  页面装载之前触发的事件

protected virtual void BeforePageLoad()

///   页面装载之后触发的事件

protected virtual void AfterPageLoad()

六、由NGSDF实现零代码开发

  通过NGSDF,您还可以不用编程同样可以搭建系统,比喻我们要建立Employee模块,你只要通过NGSDF提供的系统功能(系统框架->框架表信息)配置要您期望Employee需要显示的界面,如界面控件类型,控件长度,界面风格等,配置好之后即可增加Employee的菜单项,同时指定操作码为Employee,导航地址为”../FrameWork/AutoGenerateByTableNameForm.aspx”即可。

同样NGSDF还支持主从表,你只要对操作码(在主表后以分隔符’|’加子表名称即可,对子表数量没有限制)和导航地址(../FrameWork/AutoGenerateByTableNameMaster.aspx)做简单的改变即可,下面是主从表的应用

七、NGSDF提供的其他功能

 

1、权限控制

本框架提供了默认的权限管理模块,模块的设计基于组和角色,与具体的业务无关,可以通过此权限控制菜单(添加、删除、修改、导出、高级查询、报表)和数据表字段的修改和可见性,具体页面如下:

 

菜单权限控制

例如如果需要设置角色“浏览管理员”(只有查看)的权限,只需要通过“菜单权限”进入如下界面,按照需求设置即可

 

字段权限控制

   通过“字段权限”按钮进入字段控制界面,针对某一字段的权限控制,

如果对角色“浏览管理员”的人员基础信息的“姓名”字段设置为不可见,模块设置为不可修改,则控制后的界面如下:

  

2、菜单层次结构

利用本框架不用考虑任何功能菜单的显示问题,只要利用本框架的“系统菜单”模块配置好菜单层次结构和连接即可.

 

 

3、框架表信息维护

通过NGSDF 提供的 系统框架表配置应用系统的表信息,由于在实际应用开发中,系统数据库存在大量的表,通过提供的“系统表和框架表匹配”,自动同步数据库表(包括视图)和框架表字典信息,完成大部分的基础设置工作,包括表信息和字段信息(字段名、字段信息,PK信息、使用控件等)

还可以通过如下界面来设置表和字段信息

 

 

4持久化对象代码生成器

通过框架提供的类代码生成器,你可以实现快数持久化对象类代码实现,大量节省编码和调试配置时间,操作界面如下,代码生成有两种方法,其实是通过选择界面ListBox的一个或者多个Item项,然后执行产生代码即可,也可以同时通过输入框直接键入表名。选择框“IPersistenceControllable实现”表示是否自动产生接口IpersistenceControllable的实现代码,在此接口中可以封装业务逻辑,期望在持久化对象状态改变或者同步数据库时做的工作。

 

5、界面代码生成器

你可以通过框架提供的“列生成器”来产生DataGrid的Columns的代码和表格控件WayControlTable的Items代码,你可以通过选择表名和直接键入来生成,界面如下。在利用此页面产生代码时最好先通过“系统框架表信息”模块配置好需要产生的表的表信息和字段信息。其中选择框“AddGrid生效”表示是否启用框架表字段的“增加可见”和“网格可见”的设置,“Enable”表示对WayControlTable的Items的Enable属性是否设置

 

6、增加表

可以通过框架提供的“功能表信息配置”来增加表和字段信息,并自动和数据库表同步,页面如下:

 

 

7、自定义报表输出

通过框架提供的“报表设置”模块可以实现自定义报表,本功能支持分组报表和小计合计报表,配置界面如下:

配置好后只要在模块页面上加入报表按钮(WayImageButton类型),并设置CommandName属性为“Print”即可,或者自己在按钮下写代码:

this.Response.Redirect(string.Format(@"..\FrameWork\ReportMainFormByTableName.aspx?MenuId={0}&TableName={1}",Forceland.Web.WebUtilityCore.QueryIDFromRequest("MenuId"),

                                              “表名”))

报表页面例子如下:

 

8、数据自动导入

   可以通过框架提供的“数据导入”模块从Access文件中自动导入数据,在导入数据时操作步骤如下:

第一:通过“数据库导入”模块上传Access文件到服务器。

第二:数据到自动导入“同步数据库表结构”自动产生上传数据库表结构信息

 

第三:通过“数据导入”映射模块配置好由“第二”步产生的表结构和系统数据库表结构的关系(包括表和字段的对应关系)

第四:在通过“数据库导入”模块中的导入数据按钮自动把数据导入当前数据库。

 

9、用户操作跟踪

用户操作跟踪,本框架对用户所有操作都进行Log处理

八、总结

总的来说,利用NGSDF可以超常的提高软件开发速度,基本每个页面开发速度保持在10~20分钟,整个系统的体系结构清晰,维护扩展容易,减少设计成本。经过大量的项目使用和评估,NGSDF可以使得通常的ASP.Net项目开发节约50~70%的成本。

 

 


 

 

版权所有:UML软件工程组织