我的一种实体对象的设计方法
基类DatabaseEntity有三个方法Insert/Update/Delete,分别执行插入/更新/删除操作,Insert方法的参数values为一个键/值对的集合,表示如果传入了此集合的键/值对就会被作为插入的数据,
实现过程为:
public void Insert(NameValueCollection values)
{
System.Text.StringBuilder sqlbuilder = new System.Text.StringBuilder("INSERT INTO Prodcut");
sqlbuilder.Append("(");
for(int i=0; i<values.Count; i++)
{
sqlbuilder.Append(values.Keys[i]);
if (i != values.Count - 1)
{
sqlbuilder.Append(",");
}
}
sqlbuilder.Append(") VALUES(");
for(int i=0; i<values.Count; i++)
{
sqlbuilder.Append(values[i]);
if (i != values.Count - 1)
{
sqlbuilder.Append(",");
}
}
sqlbuilder.Append(")");
// then execute sql statement
}
Update/Delete与Insert一样的道理,都是根据传入的NameValueCollection构造出合适的SQL来执行,其中Update方法的第二个参数primarykeys为更新所需要的条件的键/值对,更新的时候更新满足primarykeys集合中key=value的条件的数据就可以了(这种条件的限制就很简单了,可能一些地方满足不了要求).
在派生类Product和MerchantProduct中,分别提供的自己的Insert/Update/Delete方法的实现。此方案与别的不一样的地方就是在每个实体类中,为每个属性单独设置一个修改标志,比如:
public class Product : DatabaseEntity
{
private int _ProductID;
public int ProductID
{
get { return _ProductID;}
set
{
_ProductID = value;
}
}
private bool _ProductNameModifyFlag;
private string _ProductName;
public string ProductName
{
get { return _ProductName;}
set
{
if (_ProductName != value)
{
_ProductNameModifyFlag = true;
_ProductName = value;
}
}
}
private bool _PriceModifyFlag;
private float _Price;
public float Price
{
get { return _Price;}
set
{
if (_Price != value)
{
_PriceModifyFlag = true;
_Price = value;
}
}
}
}
然后在Product的Update方法中就可以如下实现:
public void Update()
{
NameValueCollection values = new NameValueCollection();
if (_PriceModifyFlag)
{
values.Add("Price", Price);
}
if (_ProductNameModifyFlag)
{
values.Add("ProductName", ProductName);
}
// ……
NameValueCollection keys = new NameValueCollection();
keys.Add("ProductID", ProductID);
base.Update(values, keys);
}
就是分别判断每个属性的修改标志是否为true,如果为true那么就需要更新此属性对应的数据字段,否则不需要更新。其Insert方法不需要此判断,可以把全部的属性值都插入,而Delete方法则可以根据自己的需要执行删除(比如有些数据在数据库中是假删除的,那么就可以调用Update方法来实现)。
此方案没有涉及到专门查询的操作!查询用另外一个专门的搜索系统来实现。我在上面的代码很多细节方面值得商榷,UML图也有点不对的地方,不过细节不是重点,重点讨论这种方案模式。另外DatabaseEntity完成的功能在这里实际上是一些数据存取操作,Product和MerchantProduct也可以不从他继承,具体可以怎么合理怎么来用。
点评:此种方式的核心是Update方法,DatabaseEntity的Update和Product的Update,而Insert和Delete则比较简单。这种方式不是O/R Mapping,而是一种封装的方式。
优点:1、由于加入了修改标志的判断,不需要根据业务再写很多Update方法了,功能集中。
2、隐藏了操作的细节,给使用者一种完全面向对象的体验。
3、代码复用性高了,针对实体不需要写那么多数据库操作方法。
4、此方式在一定范围内还是比较有效,并且实际操作的代码都是自己写,性能好坏可以自己控制。
缺点:1、如果很简单就可以搞定更新的操作,那么写就先得比较繁琐,要写很多代码。
并且如果更新的需求很复杂,这种方式也不能很好的满足要求,主要是更新条件不好控制(上面已提到)。
2、不好实现事务,比如图中的ProductInfo的Insert/Update/Delete就涉及Product和MerchantProduct两个类(对应两张表),不过可以考虑使用System.EnterpriseServices.ServicedComponent(慎用)。在.Net2.0中有TransactionScope,可以解决这个问题。
3、需要专门设计细粒度的对象用来避免多张表的操作,因为DatabaseEntity并没有针对多表操作来设计,当然也可以另外设计DatabaseEntity来支持此特性。
Email: qingping.hu@gmail.com
from:http://yzx110.cnblogs.com/archive/2005/11/29/285889.html