我的一种实体对象的设计方法
我的一种实体对象的设计方法
基类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
posted on 2005-11-28 10:26 yzx110 阅读(631) 评论(11) 编辑 收藏 收藏至365Key 所属分类: 技术随笔

浙公网安备 33010602011771号
评论
# re: 我的一种实体对象的设计方法
假如能扩展到ADO.NET参数形式处理及得到存储过程的支持就更好了# re: 我的一种实体对象的设计方法
就从Insert这个方法的命名上,就不能给人以面向对象的感觉。在面向对象世界中应该使用Add这样的命名方式。
# re: 我的一种实体对象的设计方法
re 删除评论:说的有道理,这个我就没考虑到了,多谢指正。
我没用O/R Mappng,也是初次尝试这种方式。
# re: 我的一种实体对象的设计方法
我以前也这样写过,新增与删除与楼主的写法相同不过我更新时,我是直接送一个参数名值对的集合进来,动态组成SQL语句来做的
简单查询的写法也同理。
然后上面一堆方法全是自动代码生成的,数据访问层除了写一些复杂查询的方法外,需要写的代码很少
# re: 我的一种实体对象的设计方法
晕 能不能写下 NameValueCollection 类# re: 我的一种实体对象的设计方法
我晕...数据类型有各种各样,就你的方法,如果是字符串类型就成了insert into atable (name) values (我的商品)
就更不要提blob类型了
这样的语句能运行吗?
如果数据访问封装这么简单,MS的人应该失业了。你看他们把个ADO.NET搞得几复杂。
# re: 我的一种实体对象的设计方法
针对数据操作这部分,个人认为,至少要封装到ParameterCollection为参数传递的步骤吧,否则那不是要每个一个实体就都要写一遍?我简单的写了段code,你看一下
点击查看
其实最简单的就是以强类型的dataset中的table为实体,只需要封装一下与db操作的那块就好了.
这样就比较接近表模式了.而且实现起来够简单.
# re: 我的一种实体对象的设计方法
insert tables (field1,field2....) values(@field1,@field2,.....)这样就没有数据类型的问题。当然这些参数都是严格命名的。反正都是自动代码生成,也不费什么力气。
所以传进来的参数集合也是不能乱传的。
在UI层从绑定的控件中可以读得它所绑定的Field名。提交数据的时遍历一下FORM上的控件,可以自动组成一个符合要求的参数集合出来。
这种用法碰上复杂应用,FORM比较复杂,有复杂的商业逻辑的时候,当然有很多问题。但简单的增删改,查询还是可以胜任。
PS:.net写个简单数据操作的程序也比较复杂(不用DataGrid),比起DELPHI来
# re: 我的一种实体对象的设计方法
本身设计一个东西就不要求全。够用就行了。# re: 我的一种实体对象的设计方法
我更晕...>>反正都是自动代码生成,也不费什么力气
哪里说的自动代码生成?
>>够用就行了
这话等于没说,反正傻瓜都知道。傻瓜不知道的是:什么叫够用。
>>但简单的增删改,查询还是可以胜任
简单的增删改和查询还用得着做任何封装吗?难道DataSet不够用吗?难道以上设计包括加上你做的参数集合的封装一起,比DataSet有丝毫的强吗?
# re: 我的一种实体对象的设计方法
@搂主:你这只能算最最简单的对数据库操作的封装,简单到有无数的漏洞,连最简单的SQL注入都防范不了,更不要说作为一个实际可行的方案了。
“本身设计一个东西就不要求全”--这样的心态是做不出好作品的。正确的话我想应该是:“没有最好的方案,对特定的项目,选择最适合的方案就好”。
你的这个设计,脱离你的项目来讲,我可以说一句,基本没什么通用性,重用的价值几乎小到0。当然了,不排除对于你的某个项目来讲完全够用的可能。
不过,既然是写文章发到首页来,还请谦虚一些。如果只想接受拍转,不愿承受鸡蛋,那还是不要public为好