針對資料庫應用開發中大量重複勞動(建表、SQL、實體類、CRUD 代碼、頁面),本文提出「通用 DAL + 輕量 ORM + 可擴展代碼生成器」三位一體方案,顯著提升開發效率。
基於 ADO.NET 2.0 DbProviderFactory Provider 模式,支援多資料庫切換(依賴倒置)。核心特性:
public DataSet SqlExecuteDataSet(string sql, string[] parameters, params object[] values)
public DataTable SqlExecuteDataTable(string sql, string[] parameters, params object[] values)
public int SqlExecuteNonQuery(string sql, string[] parameters, params object[] values)
public DbDataReader SqlExecuteReader(string sql, string[] parameters, params object[] values)
public object SqlExecuteScalar(string sql, string[] parameters, params object[] values)
支援交易包裝:
using (var trans = new DatabaseTrans(dbHelper)) {
try {
dbHelper.SqlExecuteNonQuery(trans, "delete from Citys where CityId=@id", new[]{"@id"}, 1);
dbHelper.SqlExecuteNonQuery(trans, "delete from Citys where CityId=@id", new[]{"@id"}, 2);
trans.Commit();
} catch { trans.RollBack(); }
}
面向物件操作資料,內部仍使用參數化 SQL,效能可控。核心 API:
// 新增
var c = new Case { Title="abc", Content="呵呵", ... };
EntityBase.Insert(c);
// 修改
c.ClearInnerData(); c.CaseId = 1; c.Title = "嘿嘿";
EntityBase.Update(c);
// 刪除
c.ClearInnerData(); c.CaseId = 1;
EntityBase.Delete(c);
// 複雜查詢
var cond = new WhereCondition(c.CaseFromColName, SqlOperator.Equal, (short)CaseFrom.客服投訴)
.And(new WhereCondition(c.CreateTimeColName, SqlOperator.GreaterThan, DateTime.Now.AddDays(-1)))
.Group().Or(new WhereCondition(c.CloseUserColName, SqlOperator.Equal, "wawa"));
var list = EntityBase.Select(new[]{"Title","PostUser"}, cond);
public static void Insert(EntityBase entity) {
string sql = GetInsertSql(entity);
string[] parameters = GetParameters(entity.InnerData);
object[] values = GetParameterValues(entity.InnerData);
_db.SqlExecuteNonQuery(sql, parameters, values);
}
private static string GetInsertSql(EntityBase entity) {
var sql = new StringBuilder();
sql.AppendFormat("INSERT INTO [{0}]\r\n(", entity.TableName);
for (int i=0; i<entity.InnerData.Count; i++) {
sql.AppendFormat("[{0}]{1}", entity.InnerData[i].Key, i==entity.InnerData.Count-1?"":",");
}
sql.Append(")\r\nVALUES\r\n(");
for (int i=0; i<entity.InnerData.Count; i++) {
sql.AppendFormat("@{0}{1}", entity.InnerData[i].Key, i==entity.InnerData.Count-1?"":",");
}
sql.Append(")\r\n");
return sql.ToString();
}
WhereCondition 支援 AND/OR/Group 巢狀組合,不支援 Join 與子查詢(刻意保持輕量)。
利用 SqlConnection.GetSchema 與 CommandBehavior.KeyInfo 取得資料庫中繼資料(資料表、欄位、型別、主鍵、Identity、Nullable),映射至獨立元模型:
public class CodeModel {
public string ClassName, TableName, Namespace, PkColName;
public List Properties;
}
public class CodeProperty {
public string DbColName, PropertyName, CSharpTypeStr;
public SqlDbType DbType; public int? DbLength; public bool DbAllowNull;
public bool DbIsIdentity, DbIsPk;
public bool UiAllowEmpty, UiIsShowOn; public long? UiMaxCheck, UiMinCheck; public string UiRegxCheck;
}
實體類模板(片段):
namespace $model.namespace$ {
public class $model.classname$ : EntityBase {
$foreach.prop$ public const string $prop.property$ColName = "$prop.dbcolname$"; $endforeach$
static $model.classname$() { $foreach.prop$ _Cols.Add($prop.property$ColName); $endforeach$ }
public $model.classname$() { _tableName="$model.tablename$"; _PkName="$model.pkcolname$"; }
$foreach.prop$ private $prop.csharptype$ $prop.property2$; $endforeach$
$foreach.prop$ public $prop.csharptype$ $prop.property$ { get{return $prop.property2$;} set{$prop.property2$=value; AddInnerData("$prop.property2$",value);} } $endforeach$
protected override IList Cols { get { return _Cols; } }
public override void ConvertToEntity(...) { foreach(var item in items) { switch(item.Key) { $foreach.prop$ case $prop.property$ColName: $prop.property2$ = ($prop.csharptype$)item.Value; break; $endforeach$ } } } }
}
新增資料庫類型或輸出格式(如 DTO、Repository、Controller)只需新增模板,無需修改生成器核心。
public class User : EntityBase {
public const string UserIdColName = "UserId"; ...
private Nullable userid; ...
public Nullable UserId { get{return userid;} set{userid=value; AddInnerData("userid",value);} } ...
protected override IList Cols { get { return _Cols; } }
public override void ConvertToEntity(...) { switch(item.Key) { case UserIdColName: userid=(Nullable)item.Value; break; ... } } }
三大組件協同:DAL 解決存取通用性,ORM 解決業務表達直觀性,生成器解決重複代碼產出。團隊可據此快速建構資料庫應用,專注業務邏輯創新。