DataRabbit 轻量的数据访问框架(03) -- IOrmAccesser(续)

   本文将接着 DataRabbit 轻量的数据访问框架 -- IOrmAccesser 继续介绍IOrmAccesser的一些高级功能。这些高级功能需要DataRabbit.ORM.ISmartEntity接口的支持。注意,对于Entity class 来说,该接口并不是强制的。

(1)关于含自增字段的Entity插入

     插入后,Entity中对应自增字段的属性将被正确地赋为数据库中自增结果值。


   如果Entity class 继承了ISmartEntity接口,那么这个Entity就是一个“Smart”的Entity,IOrmAccesser针对这样的Entity,它将拥有两种特殊的能力:
(2)partial update:即部分更新的功能。即在Update一个SmartEntity对象时,只更新哪些标记为“dirty”的字段。
   比如,我们以前这样来实现“将ID为30的学生的Email更新”的功能:

            //将ID为30的学生的Email更新
            Student student = stuOrmAccesser.GetOne(new Filter(Student._ID, 30));        
            student.Email 
= "sky@299.com";
            stuOrmAccesser.Update(student);//更新除主键外的所有字段

   但是,如果Student Entity实现了ISmartEntity接口,就可以这么做:
            //将ID为30的学生的Email更新
            Student student = new Student() ;
            student.ID = 30 ;
            student.Email 
= "sky@299.com";
            stuOrmAccesser.Update(student);//仅仅更新“Email”字段

   由于指讲“Email”字段标记为“dirty”,所以在Update时,仅仅会更新“Email”字段的值。

(3)插入前检查:即在向数据库中插入一个SmartEntity对象之前,先检查该对象的状态是否正确,如果不正确,将不会插入,而是抛出InvalidEntityException异常。

   ISmartEntity接口定义与说明如下:
    public interface ISmartEntity
    {
        
/// <summary>
        
/// Clean 将所有Column字段的dirty标记设为false。
        
/// </summary>
        void Clean();

        
/// <summary>
        
/// DirtyColumnList 获取所有需要更新的Column
        
/// </summary>
        IList<string> DirtyColumnList { get; }

        
/// <summary>
        
/// Check 用于检查Entity内部状态是否一致。
        
/// 在将ISmartEntity插入(或更新)到数据库之前,DataRabbit会检查(Check)其状态是否有效,如果无效,则将抛出InvalidEntityException。
        
/// </summary>      
        bool Check(DataAccessType dataAccessType);
    }

    
/// <summary>
    
/// DataAccessType 访问数据库的几种操作类型
    
/// </summary>
    public enum DataAccessType
    {
        Query, Insert, Update, Delete
    }
   
   普通的Entity class可以通过工具自动生成,smart Entity class也可以通过工具自动生成,我写了一个简单的小工具“EntityCreator”来生成Entity class或smart Entity class。生成的Entity class代码中,Check()方法直接返回true,我们可以在这个方法内添加代码以检查当前Entity对象的状态,确保在插入该对象之前,对象的状态是一致、正确的。
   下面是针对前述的Student生成的smart Entity 代码:
Student


   最后,提供EntityCreator小工具的下载。


返回到:轻量的数据访问框架 --序  


0
0
(请您对文章做出评价)
« 上一篇:DataRabbit 轻量的数据访问框架(02) -- IOrmAccesser
» 下一篇:DataRabbit 轻量的数据访问框架(04) -- IEntityRelationLoader
posted @ 2007-03-20 11:25 zhuweisky 阅读(2685) 评论(4)  编辑 收藏 所属分类: DataRabbit

  回复  引用  查看    
#1楼2007-03-20 18:28 | 双鱼座      
不作评论,提出一点改进意见吧。
1.在属性被set的时候判断一下是否相同。如果相同的话不作任何处理。不过属性的set会有两种场景:一种是框架从数据库中导入时;另一种是由客户端代码修改时。我想象框架中应该是在读入所有属性值后再调用Clean清除标记。那你的“接口非强制”就名不符实了。
2.那个dirtyColumnList作为脏字段列表太铺张了。学学DataTable的搞法,进行版本管理。我的策略是做单一版本管理,代价比DataTable小一点,效果也差不多。当第一次有属性被修改时立即建立一个备份(我称之为影子)。一方面在RejectChanges时可以快速恢复;另一方面不必在实例中花费额外的字段保存状态。至于判定“是否有属性被修改过”,传统的做法是在实例中保存版本状态(DataTable就是这样干的),其实没有必要。直接从“影子列表”中查找,如果有,被修改过了;如果没有就是没有被修改过。在从数据库中读取值时,备份机制是不工作的,所以可以获得非常高的效率。因为实例被修改的可能性毕竟比较小,所形成的影子列表不可能很大,所以采用任何一种方式管理影子列表都没有问题。

  回复  引用  查看    
#2楼[楼主]2007-03-21 09:05 | zhuweisky      
@双鱼座:
感谢你的关注!
1.“接口非强制”指的是,如果Entity class没有实现ISmartEntity接口,仍然可以使用DataRabbit框架,只是不再有“部分更新”和“状态一致性检查”的功能。

2.DataRabbit不需要提供RejectChanges操作,所以也没有必要保存Entity的“影子”。

  回复  引用  查看    
#3楼2007-03-21 12:41 | 双鱼座      
看来你完全没有领会我的意思。
1.“接口非强制”的意思你文中已经解释得很清楚,不用怀疑我有所误解而进行补充。事实上如果不实现这个接口,谁来负责数据改动的监测?OK,如果直接使用你生成代码中的接口实现,从数据库中第一次Load的时候就会调用所有的Setter,在这一瞬间,全部都变成“脏”数据了,你只好调用Clean()方法来消除“脏”标记。另外,你的“状态一致性检查”更是名不符实。如果加载后的属性值为1,然后我再设置为1,你的实现会报告已经改变,但是实际上并没有改变。
2.我并不是推荐你实现“影子”机制,而是说你花费dirtyColumnList这样大的空间代价来保存字段的“脏”状态是不可取的。你看看List<string>的实现,你会发现我的担心不是多余。我建议你参考的方案其一是学习DataTable的版本管理;方案二是采用我曾经用过的“影子”方案。你会看到,这两个方案都比你的dirtyColumnList方案节省,而且没有效率之虞。当然,如果你不需要RejectChanges的话,可能会更简单、更节省、更高效。
实话说,看到你的回复,我对你的框架相当失望,完全失去了探究的兴趣。

  回复  引用  查看    
#4楼[楼主]2007-03-21 13:19 | zhuweisky      
@双鱼座:
(1)框架在Load返回对象之前,框架会调用Clean()方法来消除“脏”标记。
(2)关于调用Setter赋相同的值而导致字段变“脏”,确实不太好,我可以将代码生成器修改一下,在Setter中加上if判断。

还是谢谢你的建议:)