忘记数据层是第几次改版了,对数据层重新调整了一下,写点经验, 也写点总结。
内容仅供参考,大鸟飘过
基本思想:
- Ado.net是很棒的
- 数据库框架是必须的
- 单层解决方案总有不适应的时候
- 没有完美的解决方案
下面将就以上几条讨论一下:
Ado.net是很棒的:
ado.net基本上是所有数据框架的基础, 速度快, 性能优, 稳定性好
数据库框架是必须的
手动写代码绝对是个噩梦, 且不讨论跨数据库的问题, 光维护就要人命(那些数据库永久不变, 逻辑也基本不变的除外)
单层解决方案总有不适应的时候
数据层的封装多少伴随着功能、性能的缺失,也伴随灵活性的降低
没有完美的解决方案
对各种数据库的支持是一件体力活,不是专做数据层的人没必要完整实现
就着以上几点,我对数据层进行了如下分层,
第一层:provider - 功能最简单的一层,简易封装System.Data.CommonDbProviderFactory 实现对跨数据库的支持, 基本功能 CreateConnection CreateCommand CreateParameters
效果参考:
using (DbConnection conn = provider.CreateConnection("Data Source=|DataDirectory|cms.s3db;")) { if (conn.State != ConnectionState.Open) conn.Open(); ... }
第二层:Db - 对provider的拓展, 主要提供 DbConnection、DbTransaction 快关及访问的支持, 从而实现DbCommand 对 ExecuteNonQuery、ExecuteScalar、ExecuteReader、ExecuteTable 等Execute命令的支持
效果参考:
using (Db db = new Db()) { DataTable dt = db.ExecuteTable("select id,title from news_info where id>=@parameter1 and id<=@parameter2", 10, 20); ... }
第三层 Sql -这层主要实现夸数据库sql的支持, 简单的说就是t-sql的生成,这层主要有3部分组成,
- sql - 实现类似jquery语法,
- sqldata - 保存sql产生的数据, tablename, columns joins wheres
- sqlparser - 把sqldata转换为对应的sql语句
效果参考:
DataTable dt = Sql<news_info> .Select() .Join<news_category>(t => t.CategoryId, t1 => t1.Id) .Columns(t => t.Id, t => t.Title, t => t.Time_Create, t => t.Author) .Columns<news_category>(t1 => t1.Title, "CategoryTitle") .Where(t => t.Id, ">=", 7) .OrderByDesc(t => t.Id) .Limit(20) .ExecuteTable();
第四层 activerecord - 这是种见了一面就再也放不开的漂亮东西(虽然不怎么面向对象), 这层主要就是把实体类转换成sql或者把sql结构转换为实体类
效果参考:
news_info info2 = news_info.Select(2); info2.Time_Update = DateTime.Now; info2.Update(); news_info info = new news_info(); info.Title = "最新消息"; info.Insert(); info.Delete();
通过分层, 并接口公开, 最简单的 activerecord 实现, 复杂一点的Sql 实现, 最复杂的由 Db实现,
关于为什么要有Provider层:Db层肯定是可以通过ado.net直接实现provider的功能的,只是保持provider简单并且只被Db调用, 确实会使程序变得更稳健
题外话:
NHibernate更新了好多版本了, Entity Framework也出了相当多版本了。
不知道是不是依然有人和我一样不愿意去用这两个框架,
不是觉得不够好, 而是有点莫名的不喜欢