CYQ.Data 数据层框架CYQ.Data 是一款由路过秋天创作的支持多数据库应用[Txt,Xml,Access,MSSQL,Oracle,SQLite,MySql]的底层数据库操作类库,使用本类库可以轻松快速开发项目(QQ群:6033006)。 |
CYQ.Data 数据框架 实现数据的按需更新的改进
框架原理 |
|
|
| #楼主 |
首先感谢dudu发了这么一篇:博客园现代化建设—准备用Entity Framework实现数据的按需更新 在帖子的第十六楼,我留下了这样的留言: 路过秋天:
在经过前面几步的分析后,思索了一下,最终得出一个简单更优的解决方案,与大伙共享: 一:CYQ.Dtata 数据框架目前的设计方式: 1:在框架的内部的最小值赋单元里,有个bool型的IsChanged字段,来标识一个字段的值是否被改变过。 2:框架在组合SQL语句时,再根据此标识来组装相应的SQL语句。 从上面的两点看出,此设计基本上能实现按需要更新或按需要插入功能。 我们再看一下实际的应用场景: 场景一:看似完美的解决了按需更新或插入 using(MAction action=new MAction(TableNames.Blog_Users)) { action.Set(Users.ID,1); action.Set(Users.UserName,"cyq1162"); ation.Update(); } 说明: OK,由于在值赋时会改变IsChanged标识位,于是无论是组Insert或是组Update,都会实现按需更新或插入。
场景二:问题出现了 比如一个博客后台,总会有很多选项或提交更新的地方: using(MAction action=new MAction(TableNames.Blog_Users)) { action.Set(Users.ID,1); action.Set(Users.UserName,"cyq1162");//一般不会改用户名,这仅是示例 action.Set(Users.Nickname,"路过秋天");//修改昵称 acton.SetAutoPre("txt","ddl");//通过自动取值方式,省点代码,不然得写十多行赋值语句 ation.Update(true);//启用自动取值方式 } 说明: 在此情况下,所有Set的代码都会被更新,因为全都有了赋值动作了,事实上我们仅改了个别文本框的值。 假如: 我们就在设置IsChanged时,加个判断,值和以前一样,就不改变? 如此看似能解决,但又一问题又产生了,看下一场景。 场景三:按场景二的方式改进,Insert将有可能产生问题 假设我们有以下类似的应用场景: using(MAction action=new MAction(TableNames.Blog_Users)) { action.Fill(id);//查询填充一条数据,于是行或实体全有了数据。 // ...然后取值处理一些事情,然后进行一些判断......然后我们需要再添加一行新数据,再new一个新行或实体?可偏偏有时你会希望一个对象能多用几次,省点资源,于是有了以下操作 action.Set(Users.UserName,"新用户名");//重新赋值, action.Set(Users.Nickname,"刚好这昵称有人用了");//再重新赋值 ation.Insert();//插入数据,于是当然期望新添加行的数据只有包括这两个重新赋值的数据。 } 分析: OK,由于框架原先的设计,只会对赋值的语句组装SQL语句,所以我们并不担心原来的数据会产生什么影响,只要重新赋值,就可以添加新数据了。 如果: 在场景二的时候,我们加了判断,不改变IsChanged标识位了,会产生什么影响? 产生问题:NickName没有被插入,原因是因为行里本身有数据,相同值的赋值不再更改标识位的。 在一瞬间的意识流分析到以上问题后,所以有了在dudu文章下面的留言。 当然应用场景是有可能相似的,只是实现的代码或者另有不同。 二:CYQ.Data 数据框架的改进设计 在分析后问题的产生,意识流又有了一些许冲动,来了不少灵感,于是有了以下的改进方案: 1:单纯的bool型的IsChanged无法适应这种情况,那增加更多的标识类型呢? 2:于是进而转之再有了新想法:将bool型的IsChanged更改为int型的State。 于是,多了可扩展的N种状态: 0:状态未被更改;1:产生赋值动作,值相同;2:产生赋值动作,值不同。
于是,问题明朗化并得到解决: 1:产生Insert语句时,判断State>0即可 2:产生Update语句时,判断State>1即可。 3:赋值时,同样将新旧值进行判断,更改State为1或2。 至此,框架改动起来不过3分钟不到,但却完成了一项不小的功能改进。 |
游客[注册][116.54.28.*]2011/8/21 1:19:58 | #1 | |
方向错误,就什么都没意义了。 持久层不该去维护对象的属性状态,并对其负责。 只有一个例子,那就是 DataSet 系列——原因是其用于 MVC 作为通用的 Model 容器,在 View 中使用时用来记录状态变更。 而它是与具体的业务无关的——或者说 DataSet 的“业务”就是要解决这个问题的。但ORM生成的代码和ORM自己要去解决这个问题还不如只需要提供机制让业务层能够知道实体的属性值发生了变化,至于之后怎么处理,由业务层来决定(再根据决定是否调用持久层完成数据存取动作),这样才是合理的方式。 所以说,设计思想比技术实现能力更重要。先考虑设计是否合理、是否还有更合理的方案? 回复: 这个框架的场景的出现,首先,它不是一个纯ORM,虽然有扩展ORM功能。 有一种设计,是基于理论,职责,去设计。 也有一种设计,是基于简单,实用,去实现。 所以没有什么方向错不错。 正如不能拿mvc来说webform不够mvc就说webform不对。 |
发表评论
论坛公告
帖子搜索
最新帖子
最新评论
- 请教博主。我mysql的提示 V5.7.7.4 MySql.xxxx:check the tablename "tbl_site_info" is exist? error:ExeDataReader():Expression #1 of ORDER BY clause is not in SELECT list, references column 'information_schema.s1.ORDINAL_POSITION' which is not in SELECT list; this is incompatible with DISTINCT 配置如下: <?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="Conn" connectionString="host=192.168.3.101;Port=3306;Database=xxxxx;uid=root;pwd=2017" providerName="MySql.Data.MySqlClient"/> </connectionStrings> </configuration>
- 查询语句有点问题,软件启动时查询语句可以从数据库查询出数据,软件一直运行时无论怎么修改数据库,查询出来的还是老数据,不知道是为什么
- 我语句中用到了union all而且两个查询都有查询条件,action.select总是不成功,不知道有没有什么好的解决办法,谢谢
- 大神,如果我想通过一个对象(从数据映射过来的)要插入的话,我需要遍历字段然后每个set一下吗?有没有更好的方法??
- 真心好用,想问下秋天直接拼写sql怕注入吗
- V4.5后,好多方法都改变了,求来个新的日志帮助
- 請問大神V5源碼要多少錢 我是和交流過的
- 楼主,,从数据库里查出来并绑定datagridview,但是显示的都是数据库里的英文名,怎么改??好纠结啊这个。。。。
- 我想问一下,主从表添加怎样处理
- 10年就过了!!!!