.NET数据访问层基础结构设计目标:
1.完成面向对象的数据访问
2.减少调用侧代码量
3.满足可扩展的系统需求
4.保证数据一致性
其中,对于.NET访问层基础结构设计,采用如下原则。
1.对于面向对象系统,采用DataReader方式进行数据读取;
2.为了减少调用侧代码量和满足可扩展的系统需求,采用反射实现动态的属性访问;
作者参与系统使用Codeplex的项目FastReflection作为反射工具,对于对象基本属性可通过属性名字符串直接访问,
例,Teacher类有属性ClassID,我们可通过teacher.Item("ClassID")对其进行读写;
很多人担心反射的效率问题,当然自己每次生成属性访问器可达到只有4倍的效率低下,而直接使用FastReflection可能会达到近40倍的效率低下;但1000000次读写在0.7秒内完成与可扩展的目标权衡起来,还是可以采用的。
3.为了保证数据的一致性,我们采用每个数据表都有物理主键ID,类型为GUID的设计;同时使用DateTime型UpdDateTime字段来记录插入和更新时间,作为排他的基本条件。
如何保证数据排他:
用户A和用户B同时取得一条数据进行更新的同时,使用UpdDateTime作为条件,如果UpdDateTime一致则可进行更新;
反之,无法进行更新。
在编码中,我们使用ExecuteNonQuery执行更新SQL文,而对返回的影响件数进行判断;对于影响零件的情况,视为数据不一致的更新行为,报排他异常。
对于主键的使用:
小型系统一般都使用自动增长唯一标识列,都是提交数据后查询主键,使用SQLServer2005以上的系统,可以通过如下SQL文和输出参数获得自动增长的主键值:
- INSERTCategories(CategoryName)Values(@CategoryName)SET@Identity=SCOPE_IDENTITY()
其中输出参数@Identity就是返回的自动增长主键值。
而对于比较复杂的系统,如包含部分更新及全部更新和主细表同时更新的情况下,需要自己在服务器端进行主键设置,此种情况建议把主键类型设置为GUID型而不使用自动生成属性,这样就可以在更新执行之前设置主表数据主键以及详细表数据的外键并进行更新了。
4.事务控制方面,主要使用隐式事务在业务逻辑层就将事务开启。
5.对于.NET数据库访问层建议大家多使用EnterpriseLibarary的数据访问组件,优化方面可以根据自己的设计进行,同时可以使用AOP组件对结构进行优化,我们自己的项目使用PostSharp对所有层的异常处理和日志输出进行了优化。
【编辑推荐】