这一章讲述的是数据库持久化的解决方案.

在这个项目中对于数据库的操作分成了三个层次,分别为实体层,数据库访问层和业务逻辑层.

下面分别来介绍三个层次

第一个层次是实体层.这个层次的实现非常简单,就是把数据库的一张表或视图,用类来表示,表的字段用属性来表示.下面给出一个实例.

 1 public class BillInfo
 2 {
 3 #region Private member variables
 4 string _BillID = "";
 5 string _CorpID = "0000";
 6 string _BillTypeID = "0";
 7 int _PrintCount = 0;
 8 string _Passed = "F";
 9 string _Approved = "F";
10 string _Transmited = "F";
11 string _CanRead = "T";
12 string _CanWrite = "T";
13 string _SaveUser = "/";
14 string _ApproveUser = "/";
15 DateTime _SaveDate = DateTime.Today;
16 DateTime _TransmitDate = new DateTime(1900,1,1);
17 DateTime _ApproveDate = new DateTime(1900,1,1);
18 string _Reserve1 = "F";
19 string _Reserve2 = "/";
20 #endregion
21 #region Constructors
22 public BillInfo(){}
23 public BillInfo(
24 string BillID,
25 string CorpID,
26 string BillTypeID,
27 int PrintCount,
28 string Passed,
29 string Approved,
30 string Transmited,
31 string CanRead,
32 string CanWrite,
33 string SaveUser,
34 string ApproveUser,
35 DateTime SaveDate,
36 DateTime TransmitDate,
37 DateTime ApproveDate,
38 string Reserve1,
39 string Reserve2)
40 {
41 _BillID = BillID;
42 _CorpID = CorpID;
43 _BillTypeID = BillTypeID;
44 _PrintCount = PrintCount;
45 _Passed = Passed;
46 _Approved = Approved;
47 _Transmited = Transmited;
48 _CanRead = CanRead;
49 _CanWrite = CanWrite;
50 _SaveUser = SaveUser;
51 _ApproveUser = ApproveUser;
52 _SaveDate = SaveDate;
53 _TransmitDate = TransmitDate;
54 _ApproveDate = ApproveDate;
55 _Reserve1 = Reserve1;
56 _Reserve2 = Reserve2;
57 }
58 #endregion
59 #region Public Properties
60 public string BillID{get{return _BillID;}set{_BillID = value;}}
61 public string CorpID{get{return _CorpID;}set{_CorpID = value;}}
62 public string BillTypeID{get{return _BillTypeID;}set{_BillTypeID = value;}}
63 public int PrintCount{get{return _PrintCount;}set{_PrintCount = value;}}
64 public string Passed{get{return _Passed;}set{_Passed = value;}}
65 public string Approved{get{return _Approved;}set{_Approved = value;}}
66 public string Transmited{get{return _Transmited;}set{_Transmited = value;}}
67 public string CanRead{get{return _CanRead;}set{_CanRead = value;}}
68 public string CanWrite{get{return _CanWrite;}set{_CanWrite = value;}}
69 public string SaveUser{get{return _SaveUser;}set{_SaveUser = value;}}
70 public string ApproveUser{get{return _ApproveUser;}set{_ApproveUser = value;}}
71 public DateTime SaveDate{get{return _SaveDate;}set{_SaveDate = value;}}
72 public DateTime TransmitDate{get{return _TransmitDate;}set{_TransmitDate = value;}}
73 public DateTime ApproveDate{get{return _ApproveDate;}set{_ApproveDate = value;}}
74 public string Reserve1{get{return _Reserve1;}set{_Reserve1 = value;}}
75 public string Reserve2{get{return _Reserve2;}set{_Reserve2 = value;}}
76 #endregion
77 }
78 

虽然非常长,但是逻辑却是很简单的.

 

第二个层次是数据库访问层.

在这个层次上,主要是使用了sqlhelper这个类中的方法来访问数据库的.sqlhelper实际上是微软的DataAccess Application Block中实现数据库访问的一个核心类.这里就不多说了.

在我们的项目中,主要通过存储过程来对数据库操作,这也是微软所推荐的方法.

例:

 1 public bool Delete(
 2 string BillID,
 3 SqlTransaction transaction)
 4 {
 5 SqlParameter[] Params = new SqlParameter[1];
 6 Params[0= new SqlParameter("@BillID",BillID);
 7 SqlHelperParameterCache.CacheParameterSet(cnString,"ApplyBill_Del",Params);
 8 SqlHelper.ExecuteNonQuery(transaction,CommandType.StoredProcedure,"ApplyBill_Del",Params);
 9 return true;
10 }
11 

 

这个是删除的例子,下面是查询的例子:

1 public ApplyBillInfo[] GetApplyBill(
2 string BillID)
3 {
4 SqlDataReader d = SqlHelper.ExecuteReader(cnString, "ApplyBill_Sel_ByPKey",
5 BillID);
6 return GetApplyBill(d);
7 }
8 

 

查询的结果通过一个实例的数组来返回

 1 private ApplyBillInfo[] GetApplyBill(SqlDataReader d)
 2 {
 3 ArrayList c = new ArrayList();
 4 int iBillID = d.GetOrdinal("BillID");
 5 int iCorpID = d.GetOrdinal("CorpID");
 6 int iGoodsType = d.GetOrdinal("GoodsType");
 7 int iH883ID = d.GetOrdinal("H883ID");
 8 int iOwnerID = d.GetOrdinal("OwnerID");
 9 int iInvoiceNo = d.GetOrdinal("InvoiceNo");
10 int iTransName = d.GetOrdinal("TransName");
11 int iWorkCorpName = d.GetOrdinal("WorkCorpName");
12 int iMemo = d.GetOrdinal("Memo");
13 int iDeclareDate = d.GetOrdinal("DeclareDate");
14 int iEntryDate = d.GetOrdinal("EntryDate");
15 int iReserve1 = d.GetOrdinal("Reserve1");
16 int iReserve2 = d.GetOrdinal("Reserve2");
17 while(d.Read())
18 {
19 ApplyBillInfo info = new ApplyBillInfo();
20 info.BillID = d.IsDBNull(iBillID) ? String.Empty:d.GetString(iBillID).Trim();
21 info.CorpID = d.IsDBNull(iCorpID) ? String.Empty:d.GetString(iCorpID).Trim();
22 info.GoodsType = d.IsDBNull(iGoodsType) ? String.Empty:d.GetString(iGoodsType).Trim();
23 info.H883ID = d.IsDBNull(iH883ID) ? String.Empty:d.GetString(iH883ID).Trim();
24 info.OwnerID = d.IsDBNull(iOwnerID) ? String.Empty:d.GetString(iOwnerID).Trim();
25 info.InvoiceNo = d.IsDBNull(iInvoiceNo) ? String.Empty:d.GetString(iInvoiceNo).Trim();
26 info.TransName = d.IsDBNull(iTransName) ? String.Empty:d.GetString(iTransName).Trim();
27 info.WorkCorpName = d.IsDBNull(iWorkCorpName) ? String.Empty:d.GetString(iWorkCorpName).Trim();
28 info.Memo = d.IsDBNull(iMemo) ? String.Empty:d.GetString(iMemo).Trim();
29 info.DeclareDate = d.IsDBNull(iDeclareDate) ? DateTime.Today:d.GetDateTime(iDeclareDate);
30 info.EntryDate = d.IsDBNull(iEntryDate) ? DateTime.Today:d.GetDateTime(iEntryDate);
31 info.Reserve1 = d.IsDBNull(iReserve1) ? String.Empty:d.GetString(iReserve1).Trim();
32 info.Reserve2 = d.IsDBNull(iReserve2) ? String.Empty:d.GetString(iReserve2).Trim();
33 c.Add(info);
34 }
35 d.Close();
36 ApplyBillInfo[] infos = new ApplyBillInfo[c.Count];
37 for(int z = 0;z<c.Count;z++)
38 {
39 infos[z] = (ApplyBillInfo)c[z];
40 }
41 return infos;
42 }
43 

 

还有保存:

 1 public bool Save(ApplyBillInfo info,bool bInsert)
 2 {
 3 SqlParameter[] Params = new SqlParameter[13];
 4 int i = 0;
 5 Params[i++= new SqlParameter("@BillID",info.BillID);
 6 Params[i++= new SqlParameter("@CorpID",info.CorpID);
 7 Params[i++= new SqlParameter("@GoodsType",info.GoodsType);
 8 Params[i++= new SqlParameter("@H883ID",info.H883ID);
 9 Params[i++= new SqlParameter("@OwnerID",info.OwnerID);
10 Params[i++= new SqlParameter("@InvoiceNo",info.InvoiceNo);
11 Params[i++= new SqlParameter("@TransName",info.TransName);
12 Params[i++= new SqlParameter("@WorkCorpName",info.WorkCorpName);
13 Params[i++= new SqlParameter("@Memo",info.Memo);
14 Params[i++= new SqlParameter("@DeclareDate",info.DeclareDate);
15 Params[i++= new SqlParameter("@EntryDate",info.EntryDate);
16 Params[i++= new SqlParameter("@Reserve1",info.Reserve1);
17 Params[i++= new SqlParameter("@Reserve2",info.Reserve2);
18 if(bInsert)
19 {
20 SqlHelperParameterCache.CacheParameterSet(cnString,"ApplyBill_Ins",Params);
21 SqlHelper.ExecuteNonQuery(cnString,CommandType.StoredProcedure,"ApplyBill_Ins",Params);
22 }
23 else{
24 SqlHelperParameterCache.CacheParameterSet(cnString,"ApplyBill_Upd",Params);
25 SqlHelper.ExecuteNonQuery(cnString,CommandType.StoredProcedure,"ApplyBill_Upd",Params);
26 }
27 return true;
28 }
29 

 

事务处理:

 1 public bool Save(ApplyBillInfo info,bool bInsert,SqlTransaction transaction)
 2 {
 3 SqlParameter[] Params = new SqlParameter[13];
 4 int i = 0;
 5 Params[i++= new SqlParameter("@BillID",info.BillID);
 6 Params[i++= new SqlParameter("@CorpID",info.CorpID);
 7 Params[i++= new SqlParameter("@GoodsType",info.GoodsType);
 8 Params[i++= new SqlParameter("@H883ID",info.H883ID);
 9 Params[i++= new SqlParameter("@OwnerID",info.OwnerID);
10 Params[i++= new SqlParameter("@InvoiceNo",info.InvoiceNo);
11 Params[i++= new SqlParameter("@TransName",info.TransName);
12 Params[i++= new SqlParameter("@WorkCorpName",info.WorkCorpName);
13 Params[i++= new SqlParameter("@Memo",info.Memo);
14 Params[i++= new SqlParameter("@DeclareDate",info.DeclareDate);
15 Params[i++= new SqlParameter("@EntryDate",info.EntryDate);
16 Params[i++= new SqlParameter("@Reserve1",info.Reserve1);
17 Params[i++= new SqlParameter("@Reserve2",info.Reserve2);
18 if(bInsert)
19 {
20 SqlHelperParameterCache.CacheParameterSet(cnString,"ApplyBill_Ins",Params);
21 SqlHelper.ExecuteNonQuery(transaction,CommandType.StoredProcedure,"ApplyBill_Ins",Params);
22 }
23 else{
24 SqlHelperParameterCache.CacheParameterSet(cnString,"ApplyBill_Upd",Params);
25 SqlHelper.ExecuteNonQuery(transaction,CommandType.StoredProcedure,"ApplyBill_Upd",Params);
26 }
27 return true;
28 }
29 

 

位于最上面一层的是业务逻辑层,封装了相关的业务逻辑.例:

 1     public bool Save(ComeInBillInfo info,bool bInsert,SqlTransaction transaction)
 2     {
 3         Bill _bllBill = new Bill();
 4         BillInfo _infoBill = null;
 5         CustomsBill _bllCustomsBill = new CustomsBill();
 6         CustomsBillInfo _info = null;
 7         if(bInsert)
 8         {
 9             _info = new CustomsBillInfo();
10             _infoBill = new BillInfo();
11             info.BillID = _infoBill.BillID = _bllBill.CreatePKey(_bllBill.GetMaxPKey(transaction,"C"),"C");
12         }
13         else
14         {
15             BillInfo[] _billInfos = _bllBill.GetBill(info.BillID);
16             _infoBill = _billInfos[0];
17             CustomsBillInfo[] _customsBillInfos = _bllCustomsBill.GetCustomsBill(info.BillID);
18             _info = _customsBillInfos[0];
19         }
20         _info.BillID = info.BillID;
21         _info.CorpID = ManuApp.CorpID;
22         _info.GoodsType = info.GoodsType;
23         _info.H883ID = info.H883ID;
24         _info.Port = info.Port;
25         _info.EntryDate = info.EntryDate;
26         _info.DeclareDate = info.DeclareDate;
27         _info.ManageCorpID = info.ManageCorpID;
28         _info.WorkCorpID = info.WorkCorpID;
29         _info.DistrictCode = info.DistrictCode;
30         _info.TrafMode = info.TrafMode;
31         _info.TrafName = info.TrafName;
32         _info.LadingNo = info.LadingNo;
33         _info.TradeMode = info.TradeMode;
34         _info.Country = info.Country;
35         _info.CompactNo = info.CompactNo;
36         _info.TransMode = info.TransMode;
37         _info.FreightFlag = info.FreightFlag;
38         _info.Freight = info.Freight;
39         _info.FreightCurrency = info.FreightCurrency;
40         _info.StorageFlag = info.StorageFlag;
41         _info.Storage = info.Storage;
42         _info.StorageCurrency = info.StorageCurrency;
43         _info.ExtraFlag = info.ExtraFlag;
44         _info.Extra = info.Extra;
45         _info.ExtraCurrency = info.ExtraCurrency;
46         _info.Net = info.Net;
47         _info.Gross = info.Gross;
48         _info.BillNo = info.BillNo;
49         _info.Memo = info.Memo;
50         _info.Reserve1 = info.Reserve1;
51         _info.Reserve2 = info.Reserve2;
52 
53         _info.RecordNo = info.RecordNo;
54         _info.LicenseNo = info.LicenseNo;
55         _info.ApproveNo = info.ApproveNo;
56         _info.ContainerNo = info.ContainerNo;
57         _info.Dock = info.Dock;
58         _info.PackageMode = info.PackageMode;
59         _info.CutMode = info.CutMode;
60         _info.CutRate = info.CutRate;
61         _info.Pieces = info.Pieces;
62         _info.Purpose = info.Purpose;
63 
64         _infoBill.CorpID = ManuApp.CorpID;
65         _infoBill.SaveUser = ManuApp.UserName;
66         _infoBill.SaveDate = ManuApp.Today;
67         _infoBill.BillTypeID = "C";
68 
69         _bllBill.Save(_infoBill,bInsert,transaction);
70 
71         return _bllCustomsBill.Save(_info,bInsert,transaction);
72     }
73 

 

可以看到,这个函数中分别调用了前面两个层的函数.

这样设计的方法,灵活性很强,性能上也不会比直接调用sql的方法差多少.不过,我觉得它的缺点也有很多.

第一,一张表有三个类,当数据库中表很多的时候,管理起来会很复杂.而且很多时候并没有什么复杂的逻辑在里面,逻辑层的类只不过直接调用了一下访问层的方法.虽然可以通过工具来生成这些代码.

第二,就是表和表之间的关联关系没有体现出来,相信维护人员要想一下子搞清其中的关系,恐怕要费些功夫吧.

第三,把数据表中的记录读出来之后,在放到一个数组的做法,我觉得也没有什么必要,因为在.net框架中dataset,和datatable是非常有用的,何不直接返回一个dataset来显得更为直接一些.

其实在项目中有的地方也是这样处理的.

1     public DataSet GetComeInBillReportDataSet(string BillID)
2     {
3         ComeInBillDB x = new ComeInBillDB();
4         return x.GetComeInBillReport(BillID);
5     }
6 

 

当然这种设计方法,对于简单的项目也是有用的(开发起来比较快).
posted on 2007-05-21 11:21  nerozhang  阅读(2100)  评论(9编辑  收藏  举报