实战揭秘:开发.Net平台应用系统框架 (3)

本文介绍了一个实体控制层的设计方案,该层负责实体类的持久化操作,如增删改查,并为业务规则层提供数据服务。文章详细展示了Product实体的DAO类实现,包括事务处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实体控制层

解决和O-R Map的问题,需要考虑的就是实体类的持久性问题了,也就是同数据库的交互问题。实体控制层用于控制数据的基本操作,如增加、修改、删除、查询等,同时为业务规则层提供数据服务。

实体控制层的类实现IEntityDAO接口。这个接口定义了实现数据操纵的主要必要方法,包括增加、修改、删除和查找。IEntityDAO的定义如下:

public interface IEntityDAO : IDisposable
 {
  void InsertEntity(EntityData entity);
  void UpdateEntity(EntityData entity);
  void DeleteEntity(EntityData entity);
        EntityData FindByPrimaryKey(object strKeyValue);
 }


可以看到,这个接口同J2EE中EntityBean的接口定义很象,实际上,我们也是参考了EntityBean的解决方案。

下面是一个Product的DAO类的例子:

public class ProductEntityDAO: IEntityDAO
{
 private DBCommon db;  //这是数据库访问的类
 public ProductEntityDAO()
 {
  db=new DBCommon();
  db.Open();
  }
  public ProductEntityDAO(DBCommon cdb)
  {
   this.db=cdb;
  }
  // 插入一个实体
  public void InsertEntity(EntityData entity)
  {
   CheckData(entity);
   db.BeginTrans();
   try
   {
    foreach(DataRow row in 
entity.Tables["Product"].Rows)
db.exeSql(row,SqlManager.GetSqlStruct("Product","InsertProduct"));
    db.CommitTrans();
   }
   catch(Exception e)
   {
    db.RollbackTrans();
    throw e;
   }
  }
  
  //修改一个实体类
  public void UpdateEntity(EntityData entity)
  {
   CheckData(entity);
   db.BeginTrans();
   try
   {
    foreach(DataRow row in 
entity.Tables["Product"].Rows)
     if(row.RowState!=DataRowState.Unchanged)
db.exeSql(row,SqlManager.GetSqlStruct("Product","UpdateProduct"));
    db.CommitTrans();
   }
   catch(Exception e)
   {
    db.RollbackTrans();
    throw e;
   }
  }
   //删除一个实体类
  public void DeleteEntity(EntityData entity)
  {
   CheckData(entity);
   db.BeginTrans();
   try
   {
    foreach(DataRow row in 
entity.Tables["Product"].Rows)
db.exeSql(row,SqlManager.GetSqlStruct("Product","DeleteProduct"));
    db.CommitTrans();
   }
   catch(Exception e)
   {
    db.RollbackTrans();
    throw e;
   }
  }  
   //查找实体类
  public EntityData FindByPrimaryKey(object KeyValue)
  {
   EntityData entity=new EntityData("Product");
   SqlStruct 
sqlProduct=SqlManager.GetSqlStruct("Product","SelectByIDProduct");
db.FillEntity(sqlProduct.SqlString,sqlProduct.ParamsList[0],
KeyValue,entity,"Product");
  return entity;
  }
  public EntityData FindAllProduct()
  {
   EntityData entity=new EntityData("Product");
   SqlStruct 
sqlProduct=SqlManager.GetSqlStruct("Product","FindAllProduct");
db.FillEntity(sqlProduct.SqlString,null,null,entity,"Product");
   return entity;
  }
  // 校验数据数据输入的有效性
  private void CheckData(EntityData entity)
  {
if(entity.Tables["Product"].Rows[0]["ProductID"].ToString().Length>40)
    throw new ErrorClassPropertyException
("Property ProductID should be less than 40 characters");
  }
  public void Dispose()
  {
   Dispose(true);
   GC.SuppressFinalize(true);
  }
  protected virtual void Dispose(bool disposing)
  {
   if (! disposing)
   return; // we're being collected, 
   so let theGC take care of this object
   db.Close();
  }
}


同数据实体层相结合,这两部分实现了应用服务层同数据库的交互。这两个部分结合,完成了类似于J2EE中EntityBean的功能。

采用数据实体和实体控制分开的设计方法,具有以下优点:

· 避免了J2EE体系中操纵EntityBean系统资源消耗大,效率低下的缺陷。

· 解决了J2EE体系中使用EntityBean传输数据时开销大,过程复杂、效率低的缺陷。

· 可以单独修改实体结构和对实体数据的操纵,使得系统更加灵活

· 数据实体的XML定义文件和实体控制层的类可以通过工具自动生成,减轻开发工作量。

数据访问层

为了为实体控制层提供对数据库操作的服务,我们设计了这个部分。这个层次通常执行以下一些操作:

· 连接数据库

· 执行数据库操作

· 查询数据库,返回结果

· 维护数据库连接缓存

· 数据库事务调用

为了统一对数据的访问方式,我们在设计的时候,在框架的类库中包含了数据访问服务,封装了常用的对各种数据库的操作,可以访问不同类型的数据库,这样,在具体软件系统开发的时候,可以不用考虑同数据库的连接等问题,也使得应用系统在更换数据库时,不用修改原有的代码,大大简化了开发和部署工作。数据访问服务还维护数据库连接缓存,提高系统性能,以及对数据库事务调用的服务。

数据访问服务在核心类库中主要通过DBCommon类来提供对数据访问功能调用的服务。DBCommon的使用方法在上面的ProductEntityDAO中可以看出一二。更多的可以看看Demo工程中的使用。

业务规则层

业务规则层需要完成的功能是各种业务规则和逻辑的实现。业务规则完成如客户帐户和书籍订单的验证这样的任务。这是整个应用系统中最为复杂的部分,没有太多的规律可循。但是,我们在完成上面的工作后,对于这个部分的开发,也可以起到一定的简化的工作。这从下面的例子可以看到。

业务规则层的设计通常需要进行很好的建模工作。业务规则的建模,一般采用UML来进行。可以使用UML的序列图、状态图、活动图等来为业务规则建模。这个部分的工作,通常通过一系列的类之间的交互来完成。

业务规则通常要求系统能够支持事务处理(Transaction)。在这个地方,.Net提供了很方便的调用Windows Transaction Server的手段。关于这个部分的内容,各位自己阅读MSDN就非常清楚了,这里就不做详细的介绍了。

例如,在一个库存系统的入库单入库操作中,除了需要保存入库单外,在这个之前,还必须对入库单涉及的产品的数量进行修改,其代码通常如下(使用了事务处理):

public void StoreIntoWarehouse(EntityData IndepotForm)
{
DataTable tbl=IndepotForm.Tables["InDepotFormDetail"];
try
{
ProductEntityDAO ped=new ProductEntityDAO();
for(int i=0;i<tbl.Rows.Count;i++)
{
DataRow formdetail=tbl.Rows[i];
string productID=formdetail["ProductID"].ToString();
decimal
inCount=(decimal)formdetail["InCount"];
EntityData product=ped.FindByPrimaryKey(productID);
DataRow productRow=product.GetRecord("Product");
productRow["CurrentCount"]=(decimal)productRow["CurrentCount"]+inCount;
ped.UpdateEntity(product);
}
ped.Dispose();
InDepotFormEntityDAO inDepotForm=new
InDepotFormEntityDAO();
inDepotForm.InsertEntity(IndepotForm);
IndepotForm.Dispose();
ContextUtil.SetComplete();
}
catch(Exception ee)
{
ContextUtil.SetAbort();
throw ee;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值