基於Grove的.NET應用程式開發提示
前一篇中講到對於資料庫表的主鍵如果是非自動成長型的使用GROVE如何處理的例子,原文見http://blog.csdn.net/greystar/archive/2005/07/13/423644.aspx
7/13/423644.aspx.
在使用GROVE時,對於實體的一些常見操作。無非是每個實體類都配一個資料訪問類
namespace JadeSoft.Logistics.SystemInfo
{
using System;
using Grove.ORM;
using JadeSoft.Common;
[DataTable("sDepartment")]
public class Department {
Guid _OID;
String _DeptID="";
//這裡給OID屬性指明是資料庫對應的主鍵列OID列,同時OID列是非自動成長的。
[KeyField("OID",KeyType=UniqueIDType.OtherDefinition)]
public Guid OID
{
get{return this._OID;}
set
{
this._OID=value;
}
}
[DataField("DeptID")]
public String DeptID
{
get{
return this._DeptID;
}
set{
this._DeptID=value;
}
}
}
}
資料訪問類基本架構如下:
//對部門資料訪問處理
using System;
using System.Data;
using JadeSoft.Logistics.SystemInfo;
using Grove.ORM;
namespace JadeSoft.Logistics.SystemInfo.DAL
{
/// <summary>
/// DeptDataAccess 的摘要說明。
/// </summary>
public class DeptDataAccess
{
public DeptDataAccess()
{
//
// TODO: 在此處添加建構函式邏輯
//
}
/// <summary>
/// 新增一條部門記錄
/// </summary>
/// <param name="dept">部門對象</param>
public void AddNewDept(Department dept)
{
if(null==dept)
{
throw new ArgumentNullException("實體物件不可為空!");
}
try
{
ObjectOperator objOpt=new ObjectOperator();
objOpt.Insert(dept);
}
catch
{
throw ;
}
}
//其他資料處理如DELETE等。略
}
}
關鍵是在於。資料庫裡有很多表。每個表都對應這樣一個資料訪問類,是不是有點不切實際。能不能通過一個公用的介面來實現所有的實體對
象的資料訪問規則。有這樣一個想法,趕快想將此想法變為實現。(在坐公車回家的路上,我一直在想這樣一個問題。我從公司回到家差不多
要一個半小時,回家後吃完晚飯,幾分鐘時間吧,就開啟電腦開始寫代碼了).
這裡我們可以定義一個介面,讓所有的實體類都實現此介面。
using System;
namespace JadeSoft.Common
{
/// <summary>
/// 定義實體類介面,系統中所有的實體類都應符合此標準
/// </summary>
public interface IEntity
{
//主鍵我都設為GUID類型的,
System.Guid OID
{
get;
set;
}
/// <summary>
/// 該屬性標識該資料實體物件是否已被持久化過。
/// </summary>
EntityStatus IsPersist{get; set;}
/// <summary>
/// 該方法提供一個驗證該實體物件內的資料是否有效途徑。每一個資料實體類都需要實現該方法。但是在該方法中只進
行對自身資料的有效性檢查。
/// 涉及到多個執行個體的有效性驗證建議不歸在此方法中,應放在相應的控制類中進行。
/// </summary>
/// <returns>校正結果是否有效</returns>
bool Validate();
}
/// <summary>
/// 標示一個資料實體的目前狀態
/// </summary>
public enum EntityStatus
{
/// <summary>
/// 表明不存在於資料庫表中
/// </summary>
New=0,
/// <summary>
/// 被標記為需要UPdate到資料庫中
/// </summary>
Update=1,
/// <summary>
/// 被標記為需要從資料庫中Delete
/// </summary>
Delete=2,
/// <summary>
/// 表明和資料庫中相比是沒有變化的
/// </summary>
Persisted=3
}
}
然後我讓實體類實現此介面
namespace JadeSoft.Logistics.SystemInfo
{
using System;
using Grove.ORM;
using JadeSoft.Common;
[DataTable("sDepartment")]
public class Department:JadeSoft.Common.IEntity
{
Guid _OID;
String _DeptID="";
[KeyField("OID",KeyType=UniqueIDType.OtherDefinition)]
public Guid OID
{
get{return this._OID;}
set
{
this._OID=value;
this._EntityStatus=EntityStatus.Update; //資料更改,需要儲存到資料庫中
}
}
[DataField("DeptID",Size=30)]
public String DeptID
{
get{
return this._DeptID;
}
set{
this._DeptID=value;
this._EntityStatus=EntityStatus.Update; //資料更改,需要儲存到資料庫中
}
}
#region IEntity 成員
public bool Validate()
{
if(this._DeptID.Length==0)
{
return false;
}
if(this._DeptName.Length==0)
{
return false;
}
return true;
}
//對象狀態
private EntityStatus _EntityStatus=EntityStatus.New;
public JadeSoft.Common.EntityStatus IsPersist
{
get
{
// TODO: 添加 Department.IsPersist getter 實現
return _EntityStatus;
}
set
{
_EntityStatus=value;
}
}
#endregion
}
}
下面我可以寫一個公用的資料庫訪問類,用於對所有的實體的資料訪問目的.
using System;
using Grove.ORM;
using System.Data;
using JadeSoft.Common;
using System.Collections;
namespace JadeSoft.Logistics.SystemInfo.DAL
{
/// <summary>
/// 對一般實體物件的通用處理。增刪改查等功能
/// </summary>
public class CommonDataAccess
{
ObjectOperator objOpt=new ObjectOperator();
public CommonDataAccess()
{
//
// TODO: 在此處添加建構函式邏輯
//
}
public void UpdateObject(IEntity entity)
{
if(entity==null)
{
throw new ArgumentNullException("實體物件不可為空!");
}
try
{
//對象是新產生的
if(entity.IsPersist==EntityStatus.New)
{
objOpt.Insert(entity);
entity.IsPersist=EntityStatus.Persisted; //更新完成後對象狀態
}
else if(entity.IsPersist==EntityStatus.Update)
{
objOpt.Update(entity);
}
else if(entity.IsPersist==EntityStatus.Delete)
{
objOpt.Remove(entity);
}
}
catch(Exception ex)
{
throw ex;
}
}
public IEntity Retrieve(Type type,Guid OID)
{
return (IEntity)objOpt.Retrieve(type,OID);
}
/// <summary>
/// 根據所需類型查詢出所有的對象。
/// </summary>
/// <param name="type">所需類型,業務實體</param>
/// <returns>對象數組</returns>
public ArrayList Retrieves(Type type)
{
ObjectQuery oquery=new ObjectQuery(type);
return objOpt.GetObjectSet(oquery);
}
/// <summary>
/// 根據所需類型查詢出所有的對象。
/// </summary>
/// <param name="type">所需類型,業務實體</param>
/// <param name="FilterExpression">過濾運算式,和SQL中的WHERE是一樣。如this.UserName='greystar'</param>
/// <returns>對象數組</returns>
public ArrayList Retrieves(Type type,string FilterExpression)
{
ObjectQuery oquery=new ObjectQuery(type,FilterExpression);
return objOpt.GetObjectSet(oquery);
}
/// <summary>
/// 根據所需類型查詢出所有的對象。
/// </summary>
/// <param name="type">所需類型,業務實體</param>
/// <param name="FilterExpression">過濾運算式,和SQL中的WHERE是一樣。如this.UserName='greystar'</param>
/// <returns>資料集對象</returns><
public DataSet RetrieveDataSet(Type type,string FilterExpression)
{
ObjectQuery oquery=new ObjectQuery(type,FilterExpression);
return (DataSet)objOpt.GetObjectSource(oquery);
}
/// <summary>
/// 根據所需類型查詢出所有的對象。
/// </summary>
/// <param name="type">所需類型,業務實體</param>
/// <returns>資料集對象</returns>
public DataSet RetrieveDataSet(Type type)
{
ObjectQuery oquery=new ObjectQuery(type);
return (DataSet)objOpt.GetObjectSource(oquery);
}
}
}
接下面我們可以試一下。這樣的處理能行嗎。當ObjectOperator對象在資料操作時能識別出IENTITY對象的原始類型嗎。
我們可以用代碼來測試一下。
CommonDataAccess cda=new CommonDataAccess();
Department dpt=new Department();
dpt.OID=System.Guid.NewGuid();
dpt.DeptID="greystar";
cda.UpdateObject(dpt);//儲存對象
代碼運行一切正常。資料庫操作成功。這樣的話,我只要讓每個實體類都實現IENTITY介面。就不用再寫任何資料存取碼了。
這個主意是不是很好。