遗忘海岸

江湖程序员 -Feiph(LM战士)

导航

Subsonic中的MarkOld与MarkNew的一些使用

 

  有这样的需要,数据库里有张表,每次保持记录时需要先判断这条记录是否存在(根据某些列的值是否相等)来选择更新(Update)或添加(Insert),在使用Subsonic时,一般会先根据条件列,来尝试读取,然后使用Save保存,系统自己来判断是使用更新还是插入,如下代码:

 CollectionCompany company=new CollectionCompany();
 company.LoadAndCloseReader(CollectionCompany.Query().WHERE("列1", value1).AND("列2", value2).ExecuteReader());

 //如果加载成功IsLoaded为true, IsNew变成false
//当IsNew为false时,调用Save()时,生成成SQL语句是Update,反之为Insert
//另外当IsNew为false时,生成的Update语句中如:
// update CollectionCompany Set xxx='xxx',yyy='yyy'... where id=1
//其中更新的具体列为DirtyColumns中的列

 if(!company.IsLoaded){
  company.Id=GetMaxId();//数据库中不存在--新记录,生成一个新的Id.

 }

 company.Title="xxxx";
 company.Tel="xxxx";
 //......其他列
 company.Save();

 一般情况下程序代码都类似上面给出的代码,这些情况下你不需要自己来调用MarkOld(),或MarkNew()
 但是有些应用下你也许需要自己手动来调用这些方法,那么请注意以下一些说明

 需要注意的是在new一个实体类后,如:CollectionCompany company=new collectionCompany(),在调用company.MarkOld之前,对company的属性(列)的任何付值都不会在DirtyColumns中添加对应的列,因此如果你先对属性进行操作而后调用company.MarkOld() 方法,那么当你在调用company.Save()时,会发现Update的Set 后面没有具体的列的错误,上面的company.LoadAndCloseReader方法在读取成功时会自动调用company.MarkOld(),因此下面进行的Save()对应的是Update方法,而Update Set 后面的列,是Load 方法后对属性进行更新的列(包括 Title,Tel 等)

   最近在做一个采集程序时就碰到了这个问题,使用sql 2000,vs2005 ,跟subsonic来做,一般做这些程序能简单就简单,能省就省,但是考虑到采集规则有可能会变,故特地把采集规则放到一个独立的项目中去,并且不打算在这个项目中放数据库操作代码,但是这个项目中使用Subsonic生成的表名对应类(如CollectionCompany) 做实体类, 当然最好实体类不要带状态,但是Subsonic生成的同表名类不是纯粹的实体类.当我在winform 中判断记录已经存在后,会使用存在记录的Id,付值给采集规则项目类反回的实体类,结果在调用Save()时就出现了Update Set后面没列的错误,解决办法是在采集规则中对新创建的类马上调用MarkOld方法如:
CollectionCompany company=new CollectionCompany()

company.MarkOld();
.......
return company;
这样做问题是有些不必要的列(用于条件判断的列)也会在Update Set后面中,但是不用在采集规则类中调用Load方法,(现在想想为什么不调用呢?也许当时就不想调用把,呵呵)


 

posted on 2008-12-05 11:48  遗忘海岸  阅读(603)  评论(0编辑  收藏  举报