C# .NET更智能的数据库操作的封装完整版(重构)

 

前述:

  第一次发表文章,不过是对数据库简单的封装,主要是阐述下思路。那么在上篇文章,在大家的指导下和提出意见,并自己对代码进行了思考。在这两天我重构了新的框架,我觉得我写的可以称得上框架,为什么?请大家往下看。不过在项目中没有很多注释。笔者除了课余学习时候,大部分时间在完成学校的功课,没有许多时间,所以也就偷下懒,请大家体谅。

  这次框架分为几个部分:拼接数据库语句、数据库执行、数据库连接控制、异常类、用户使用的DbHelper。等下我回用文字和图还分析这个部分。经过重构后,类增多了,而且能够极大的支持开闭原则,我应该说就是与实际数据库无关,而且在上层使用中,不需要在引用system.Data.SqlClient这样实际访问的东西。虽然笔者只写了sql server的实例,但是如果扩展其他的数据库,也无需大规模的修改旧的代码,并且使用参数,能够防止注入攻击,支持事务。

  好,先看怎么使用框架。

DbHelper helper = new DbHelper();
helper.createConnection("MyConnection","Data Source=CN-20161106HMJI;Initial Catalog=ShopInfo;Integrated Security=True",DbType.SQL); PlaceInfo model = helper.ExcuteString(o => o.From("PlaceInfo").Select().AndWhere("SAddNo", 1)).ToModel<PlaceInfo>();
Console.Read();

  上面是使用的一个例子,创建连接字符串,然后查询获取实例,已经没有打开数据库,或者是command的语句,使用起来是否十分简单,上面这句运行没有问题的,因为框架灵活度太大,测试的话不能所有都包含,这也是没办法,接下来跟着文章,一步步分析。

  上次说,链式编程很好用,所以这次同样是链式编程,但这次更为强大。大家知道,dal的链式编程,主要是得到数据,而得到数据无非是对数据库查询语言进行封装。所以,在框架上,我封装了一个拼接语句的类,里面包含了我认为比较常用的数据库语句,支持order by。还有最强大的是,能够支持嵌套查询!也就是封装的sql语句可以是

select * from tableName where Id in(select id from tablename where ...)...这样子的。使用起来十分的方便。而且还有排序order by,等,可以在使用这套框架封装更使用的方法。

  第二个新增的是连接控制,这个是这套框架的关键,因为框架不能占用内存,所以无论在拼接查询语句,还是在执行部分,都没有对数据库创建的语句,而是采用注入式,通过连接控制类,创建好数据库连接后,注入到所需要的部分中。而且这里控制了最耗性能的反射,对模型中的属性进行反射,都是耗时间,所以这里设置了缓存,对已经创建过对象的保存在这里,在拼接数据库语句或者是执行阶段需要用到,注入到其中,就可以省下时间。

  第三个增加的是异常类,不过我封装的比较简单,里面就一个可重载的方法,这个是用来发生异常时候,用户能够自己设置发生错误之后应该做什么(比如保存到日志)而定的。

  最后一个新增的是释放资源,因为对数据库连接,数据库连接数目比较少,但是command的数目在一般项目可就不是这样。可能大家为了方便,所以使用的时候尽情的new这样,那在我的框架设置了一个集合,专门存放command的,在用完后能够释放资源。因为考虑到在事务执行时候不能够对comand进行释放,所以在释放时候还做了判断。把有事务的command放到在事务执行后释放。

  看完上边的功能,是不是觉得十分强大,因为这个框架理解和实现起来都不容易,所以笔者尽可能的让大家明白,知道我是怎么一步步完成的。

  现在进入正题,先看下简单的结构图,看上去比较简单,不是我不会绘图,我在完成其他项目时候,都有完整的文档和图,因为现在没有太多时间,而且用软件画实在太慢了,所以大家将就的看吧。

  上图就是我框架的结构图。箭头代表关联,从下到上,代表底层到用户使用的层次。框架是支持对数据库的扩展,上边三个部分写继承抽象类就是如此,因为这几个其实就是实际数据库会使用到,所以使用工厂模式,这样就能够扩展其他了。

  好了,看完图,就开始讲解代码。

  我第一步是从数据库拼接语句开始做的,因为这个虽然还不算底层,但是相对于其他可以独立,那么看下这一跪部分的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Dal
{
public interface IDbCode
{ /// <summary>
/// 数据库执行表、视图、存储过程等对象
/// </summary>
/// <param name="Object">名称</param>
/// <returns></returns>
IDbCode From(object Object); /// <summary>
/// 查询
/// </summary>
/// <param name="Fields">查询的字段</param>
/// <returns></returns>
IDbCode Select(string Fields = "*"); /// <summary>
/// 删除
/// </summary>
/// <returns></returns>
IDbCode Delete(); /// <summary>
/// 更新
/// </summary>
/// <param name="model">更新对象</param>
/// <param name="Fields">更新字段</param>
/// <returns></returns>
IDbCode Update(object model,string Fields = ""); /// <summary>
/// 插入
/// </summary>
/// <param name="model">插入对象</param>
/// <param name="Fields">插入字段</param>
/// <returns></returns>
IDbCode Insert(object model,string Fields = ""); /// <summary>
/// 与条件
/// </summary>
/// <param name="Where">条件字符串</param>
/// <returns></returns>
IDbCode AndWhere(string Where);
/// <summary>
/// 与条件
/// </summary>
/// <param name="Field">字段</param>
/// <param name="Value">值</param>
/// <returns></returns>
IDbCode AndWhere(string Field,object Value); /// <summary>
/// 与条件
/// </summary>
/// <param name="Field">条件字段</param>
/// <param name="Select">嵌套查询条件委托</param>
/// <returns></returns>
IDbCode AndWhere(string Field, Func<IDbCode, string> Select); /// <summary>
/// 与条件
/// </summary>
/// <typeparam name="T">值的类型</typeparam>
/// <param name="Field">条件字段</param>
/// <param name="Values">值</param>
/// <returns></returns>
IDbCode AndWhere<T>(string Field,List<T> Values); /// <summary>
/// 或条件
/// </summary>
/// <param name="Where">条件字符串</param>
/// <returns></returns>
IDbCode OrWhere(string Where); /// <summary>
/// 或条件
/// </summary>
/// <param name="Field">条件字段</param>
/// <param name="Value">值</param>
/// <returns></returns>
IDbCode OrWhere(string Field, object Value); /// <summary>
/// 或条件
/// </summary>
/// <param name="Field">条件字段</param>
/// <param name="Select">嵌套条件</param>
/// <returns></returns>
IDbCode OrWhere(string Field, Func<IDbCode, string> Select); /// <summary>
/// 或条件
/// </summary>
/// <typeparam name="T">值类型</typeparam>
/// <param name="Field">条件字段</param>
/// <param name="Values">值</param>
/// <returns></returns>
IDbCode OrWhere<T>(string Field, List<T> Values); /// <summary>
/// Top 语句
/// </summary>
/// <param name="topCount"></param>
/// <returns></returns>
IDbCode Top(int topCount); /// <summary>
/// 排序从小到大
/// </summary>
/// <param name="Field">排序字段</param>
/// <returns></returns>
IDbCode OrderByAsc(string Field); /// <summary>
/// 排序从大到小
/// </summary>
/// <param name="Field">排序字段</param>
/// <returns></returns>
IDbCode OrderByDesc(string Field); /// <summary>
/// 多表查询时候必须加的条件
/// </summary>
/// <param name="Fields">在两张表中的相同字段</param>
/// <returns></returns>
IDbCode ForMulTable(string Fields); string ToString(); /// <summary>
/// 清空缓存
/// </summary>
/// <returns></returns>
IDbCode Clear(); IDbCode CreateCode(string sql); object Paras
{
get;
}
void Dispose();
}
}

继承它的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Reflection; namespace Dal
{
public class SQLCode :IDbCode
{
string Object;
StringBuilder ExcuteString = new StringBuilder();
List<SqlParameter> paras;
Dictionary<string, List<PropertyInfo>> pro;
static string[] s = { "select", "delect", "update", "insert" }; public SQLCode()
{
paras = new List<SqlParameter>();
}
public SQLCode(Dictionary<string, List<PropertyInfo>> pro)
{
paras = new List<SqlParameter>();
this.pro = pro;
}
public SQLCode(List<SqlParameter> paras, Dictionary<string, List<PropertyInfo>> pro)
{
this.paras = paras;
this.pro = pro;
}
public IDbCode From(object Object)
{
Type t = Object.GetType();
if(t.Name.ToLower().Equals("string"))
{
this.Object = Object.ToString();
}else
{
this.Object = t.Name;
} return this;
} public IDbCode Select(string Fields = "*")
{
if (this.Object.Length <= 0)
return this;
if (!Check(0))
return this;
ExcuteString.AppendLine("select " + Fields +" from "+ this.Object);
ExcuteString.AppendLine(" where 1 = 1 ");
return this;
} bool Check(int Type)
{
int flag = 0;
string b = ExcuteString.ToString();
for (int i = 0; i < s.Length; i++)
if(i!=Type)
flag += b.Contains(s[i]) ? 1 : 0;
return flag == 0;
} public IDbCode Delete()
{
if (Object.Length <= 0)
return this;
if (!Check(1))
return this;
ExcuteString.AppendLine("delete " + this.Object);
ExcuteString.AppendLine(" where 1 = 1 ");
return this;
} public IDbCode Update(object model, string Fields = "")
{
if (this.Object.Length <= 0)
return this;
if (!Check(2))
return this; Type t = model.GetType();
if (t.Name != Object)
return this; ExcuteString.AppendLine("update "+this.Object +" set "); List<PropertyInfo> p;
if(pro.ContainsKey(t.Name))
{
p = pro[t.Name];
}else
{
p = t.GetProperties().ToList();
pro.Add(t.Name, p);
}
string f = "";
if(Fields.Length==0)
{
p.ForEach(o =>
{
f += o.Name + " = @" + o.Name;
paras.Add(new SqlParameter(o.Name, o.GetValue(model, null)));
});
}else
{
string[] a = Fields.Split(','); p.ForEach(o =>
{
if (a.Contains(o.Name))
{
f += o.Name + " = @" + o.Name + ",";
paras.Add(new SqlParameter(o.Name, o.GetValue(model, null)));
}
});
}
ExcuteString.AppendLine(f);
ExcuteString.AppendLine("where 1 = 1"); return this;
} public IDbCode Insert(object model, string Fields = "")
{
if (this.Object.Length <= 0)
return this;
if (!Check(3))
return this; Type t = model.GetType();
if (t.Name != Object)
return this; ExcuteString.AppendLine("insert " + this.Object); List<PropertyInfo> p;
if (pro.ContainsKey(t.Name))
{
p = pro[t.Name];
}
else
{
p = t.GetProperties().ToList();
pro.Add(t.Name, p);
} string f = "( ";
string f1 = "values( "; if (Fields.Length == 0)
{
p.ForEach(o =>
{
f += o.Name+",";
paras.Add(new SqlParameter(o.Name, o.GetValue(model, null)));
f1 += "@" + o.Name + ",";
});
}
else
{
string[] a = Fields.Split(','); p.ForEach(o =>
{
if (a.Contains(o.Name))
{
f += o.Name + ",";
paras.Add(new SqlParameter(o.Name, o.GetValue(model, null)));
f1 += "@" + o.Name + ",";
}
});
}
f = f.Remove(f.LastIndexOf(','), 1) + " ) ";
f1 = f1.Remove(f1.LastIndexOf(','), 1) + " ) ";
ExcuteString.AppendLine(f);
ExcuteString.AppendLine(f1);
return this;
} public IDbCode AndWhere(string Where)
{
ExcuteString.AppendLine(" and " + Where);
return this;
} public IDbCode AndWhere(string Field, object Value)
{
ExcuteString.AppendLine(" and " + Field + " = @" + Field);
paras.Add(new SqlParameter(Field, Value));
return this;
} public IDbCode AndWhere(string Field, Func<IDbCode, string> Select)
{
ExcuteString.AppendLine(" and " + Field + " in " + Select(new SQLCode(this.paras,this.pro)));
return this;
} public IDbCode AndWhere<T>(string Field, List<T> Values)
{
string value = "("; Values.ForEach(o =>
{
value += o + ",";
});
ExcuteString.AppendLine(" and " + Field + " in " + value.Remove(value.LastIndexOf(','), 1) + ")");
return this;
} public IDbCode OrWhere(string Where)
{
ExcuteString.AppendLine(" or " + Where);
return this;
} public IDbCode OrWhere(string Field, object Value)
{
ExcuteString.AppendLine(" or " + Field + " = @" + Field);
paras.Add(new SqlParameter(Field, Value));
return this;
} public IDbCode OrWhere(string Field, Func<IDbCode, string> Select)
{
ExcuteString.AppendLine(" or " + Field + " in " + Select(new SQLCode(this.paras,this.pro)));
return this;
} public IDbCode OrWhere<T>(string Field, List<T> Values)
{
string value = "("; Values.ForEach(o =>
{
value += o + ",";
});
ExcuteString.AppendLine(" or " + Field + " in " + value.Remove(value.LastIndexOf(','), 1) + ")");
return this;
} public IDbCode Top(int topCount)
{
if (!ExcuteString.ToString().Contains(s[0]))
return this;
ExcuteString.Replace("select", "select top " + topCount +" ");
return this;
} bool CheckHasOrderBy()
{
return this.ExcuteString.ToString().Contains("order by");
}
public IDbCode OrderByAsc(string Field)
{
if (CheckHasOrderBy())
ExcuteString.AppendLine("," + Field + " asc");
else
ExcuteString.AppendLine(" order by " + Field+" asc"); return this;
} public IDbCode OrderByDesc(string Field)
{
if (CheckHasOrderBy())
ExcuteString.AppendLine("," + Field + " desc");
else
ExcuteString.AppendLine(" order by " + Field + " desc"); return this;
} public IDbCode ForMulTable(string Fields)
{
List<string> tables = this.Object.Split(',').ToList();
Fields.Split(',').ToList().ForEach(o =>
{
for (int i = 0; i < tables.Count - 1; i++)
{
ExcuteString.AppendLine(" and " + tables[i] + "." + o + " = " + tables[i + 1] + "." + o);
}
});
return this;
} public override string ToString()
{
return this.ExcuteString.ToString();
} public IDbCode Clear()
{
pro.Clear();
return this;
} public IDbCode CreateCode(string sql)
{
ExcuteString.AppendLine(sql);
return this;
} public object Paras
{
get
{
return this.paras;
}
} public void Dispose()
{
this.pro = null;
}
}
}

  如果有看过上次的文章,那么就知道这里部分方法用到反射,获取其中的属性来拼写语句。没什么难的,大家看到里面有许多的if条件,是我避免在链式组合时候,用户随便乱时候而设置的。这部分都是对字符串处理。

  第二部分是执行语句,这个相信大家写多了,先给代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient; namespace Dal
{
public interface IDbExcute
{
T ToModel<T>(IDbCode code, CommandType type = CommandType.Text)
where T : class,new(); List<T> ToList<T>(IDbCode code,CommandType type = CommandType.Text)
where T : class,new(); object ToResult(IDbCode code, CommandType type = CommandType.Text); int ExcuteResult(IDbCode code, CommandType type = CommandType.Text); DataTable ToDataTable(IDbCode code, CommandType type = CommandType.Text); DataSet ToDataSet(IDbCode code, CommandType type = CommandType.Text); void OpenConnection();
void CloseConnection(); void Dispose(object tran); void BeginTransation(string Name);
void Commit();
void RollBack();
}
}

上面就是支持整个框架的执行方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Reflection; namespace Dal
{
public class SQLExcute : IDbExcute
{
SqlConnection conn;
Dictionary<string, List<PropertyInfo>> pro;
Dictionary<string, SqlCommand> command;
SqlTransaction tran = null; public SQLExcute(SqlConnection conn, Dictionary<string, List<PropertyInfo>> pro)
{
this.conn = conn;
this.pro = pro;
command = new Dictionary<string, SqlCommand>();
} public List<T> ToList<T>(IDbCode code,CommandType type = CommandType.Text)
where T:class,new()
{
List<T> list = new List<T>();
string name = DateTime.Now.ToString();
command.Add(name, new SqlCommand());
SqlCommand com = command[name];
com.Connection = conn;
com.CommandText = code.ToString();
com.CommandType = type;
setCommand(com, (List<SqlParameter>)code.Paras); Type t = typeof(T);
List<PropertyInfo> pros;
if(pro.ContainsKey(t.Name))
{
pros = pro[t.Name];
}else
{
pros = t.GetProperties().ToList();
pro.Add(t.Name, pros);
} try
{
this.OpenConnection();
using (SqlDataReader reader = com.ExecuteReader())
{
while(reader.Read())
{
T model = new T();
pros.ForEach(o =>
{
if(ReaderExists(reader,o.Name))
{
o.SetValue(model, reader[o.Name], null);
}
});
list.Add(model);
}
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
this.Dispose(name);
this.CloseConnection();
} return list;
} public bool ReaderExists(SqlDataReader reader, string columnName)
{
//reader.GetSchemaTable().DefaultView.RowFilter = "ColumnName= '" + columnName + "'";
//return (reader.GetSchemaTable().DefaultView.Count > 0);
return reader.GetSchemaTable().Select("ColumnName='" + columnName + "'").Length > 0;
}
public void Dispose(string name)
{
if(command.ContainsKey(name))
{
SqlCommand com = command[name];
command.Remove(name);
com.Dispose();
}
if (command.Count <= 0)
this.CloseConnection();
} public void Dispose(object tran)
{
List<string> list = command.Keys.ToList();
list.ForEach(o =>
{
if(command[o].Transaction!=null&&command[o].Transaction==(SqlTransaction)tran)
{
this.Dispose(o);
}
});
} public object ToResult(IDbCode code, CommandType type = CommandType.Text)
{
string name = DateTime.Now.ToString();
command.Add(name, new SqlCommand());
SqlCommand com = command[name];
com.Connection = conn;
com.CommandText = code.ToString();
com.CommandType = type;
setCommand(com, (List<SqlParameter>)code.Paras); object result =null;
try
{
this.OpenConnection();
result = com.ExecuteScalar();
}
catch (Exception ex)
{
DoException();
throw ex;
}finally
{
this.Dispose(name);
this.CloseConnection();
} return result;
} private void DoException()
{
new DbException().Done();
} public int ExcuteResult(IDbCode code, CommandType type = CommandType.Text)
{
string name = DateTime.Now.ToString();
command.Add(name, new SqlCommand());
SqlCommand com = command[name];
com.Connection = conn;
com.CommandText = code.ToString();
com.CommandType = type;
setCommand(com, (List<SqlParameter>)code.Paras); int result = 0;
try
{
this.OpenConnection();
if (tran != null)
com.Transaction = (SqlTransaction)tran;
result = com.ExecuteNonQuery();
}
catch (Exception ex)
{
DoException();
throw ex;
}
finally
{
if (tran == null)
Dispose(name);
this.CloseConnection();
}
return result;
} public System.Data.DataTable ToDataTable(IDbCode code, CommandType type = CommandType.Text)
{
string name = DateTime.Now.ToString();
command.Add(name, new SqlCommand());
SqlCommand com = command[name];
com.Connection = conn;
com.CommandText = code.ToString();
com.CommandType = type;
setCommand(com, (List<SqlParameter>)code.Paras); DataTable dt = new DataTable();
try
{
using(SqlDataAdapter adapter = new SqlDataAdapter(com))
{
adapter.Fill(dt);
}
}
catch (Exception ex)
{
DoException();
throw ex;
}finally
{
Dispose(name);
} return dt;
} public void setCommand(SqlCommand com,List<SqlParameter> paras)
{
paras.ForEach(o =>
{
com.Parameters.Add(o);
});
} public System.Data.DataSet ToDataSet(IDbCode code, CommandType type = CommandType.Text)
{
string name = DateTime.Now.ToString();
command.Add(name, new SqlCommand());
SqlCommand com = command[name];
com.Connection = conn;
com.CommandText = code.ToString();
com.CommandType = type;
setCommand(com, (List<SqlParameter>)code.Paras); DataSet dt = new DataSet();
try
{
using (SqlDataAdapter adapter = new SqlDataAdapter(com))
{
adapter.Fill(dt);
}
}
catch (Exception ex)
{
DoException();
throw ex;
}
finally
{
Dispose(name);
} return dt;
} public T ToModel<T>(IDbCode code, CommandType type = CommandType.Text)
where T : class,new()
{
string name = DateTime.Now.ToString();
command.Add(name, new SqlCommand());
SqlCommand com = command[name];
com.Connection = conn;
com.CommandText = code.ToString();
com.CommandType = type;
setCommand(com, (List<SqlParameter>)code.Paras); Type t = typeof(T);
List<PropertyInfo> p = null;
if(pro.ContainsKey(t.Name))
{
p = pro[t.Name];
}else
{
p = t.GetProperties().ToList();
pro.Add(t.Name, p);
}
T model = new T(); try
{
this.OpenConnection();
using(SqlDataReader reader = com.ExecuteReader())
{
if(reader.Read())
{
p.ForEach(o =>
{
if(ReaderExists(reader,o.Name))
{
o.SetValue(model, reader[o.Name], null);
}
});
}
}
}
catch (Exception ex)
{
DoException();
throw ex;
}
finally
{
Dispose(name);
this.CloseConnection();
} return model;
} public void OpenConnection()
{
if (this.conn.State != ConnectionState.Open)
this.conn.Open();
} public void CloseConnection()
{
command.Values.ToList().ForEach(o =>
{
if (o.Transaction != null)
return;
}); if (this.conn.State != ConnectionState.Closed)
this.conn.Close();
} public void BeginTransation(string Name)
{
tran = conn.BeginTransaction(Name);
} public void Commit()
{
tran.Commit();
Dispose(tran);
tran = null;
} public void RollBack()
{
tran.Rollback();
Dispose(tran);
tran = null;
}
}
}

  具体类中,主要设计了最重要的执行方法外,还像刚开始所述,设置了List,就是用来存放command对象,在执行完成时候时候它会自己释放。跟这个类配合使用的是异常类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Dal
{
public class DbException
{
public virtual void Done()
{ }
}
}

只有短短几句话,这就是用于使用者想发生异常想它干什么而设置的。

其实封装到这里,整个框架的支持已经形成,但是用户不能直接操作底层,而且还需要怎么对数据库进行实例,所以还要对上进行封装,下一步,往上走,数据库实例部分。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace Dal
{
public interface IDbInstance
{
/// <summary>
/// 数据库名称
/// </summary>
string Name
{
get;
} /// <summary>
/// 获取执行语句类
/// </summary>
IDbExcute Excute
{
get;
} /// <summary>
/// 获取连接字符串
/// </summary>
string ConnectionString
{
get;
}
/// <summary>
/// 开启事务
/// </summary>
/// <param name="TranName">事务名称</param>
/// <returns></returns>
object getTransation(string TranName); /// <summary>
/// 获取拼写字符串类
/// </summary>
IDbCode Code
{
get;
}
}
}

实现它的具体类包含所有的底层的操作,其实就是可以说是一个数据库实例了,创建一个就相当于一个数据库。里面将上边封装的类都在这里使用。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Reflection; namespace Dal
{
public class SQLInstance :IDbInstance
{
private SqlConnection conn;
private IDbExcute excute;
Dictionary<string, List<PropertyInfo>> pro;
private string name;
private string connectionString;
private SqlTransaction tran = null;
public SQLInstance(string Name,Dictionary<string,List<PropertyInfo>> pro, string ConnectionString)
{
this.name = Name;
this.connectionString = ConnectionString;
conn = new SqlConnection(ConnectionString);
this.pro = pro;
excute = new SQLExcute(conn,pro);
} public string Name
{
get
{
return this.name;
}
}
public IDbExcute Excute
{
get
{
return this.excute;
}
} public string ConnectionString
{
get
{
return this.connectionString;
}
} public object getTransation(string TranName)
{
return this.conn.BeginTransaction(TranName);
} public IDbCode Code
{
get
{
return new SQLCode(pro);
}
}
}
}

接下来是控制连接的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection; namespace Dal
{
public class DbControl
{
//数据库服务
private static Dictionary<string, IDbInstance> Server = new Dictionary<string, IDbInstance>();
//存放缓存
private static Dictionary<string, List<PropertyInfo>> pro = new Dictionary<string, List<PropertyInfo>>();
private static DbControl control = new DbControl();
public static DbControl getInstance()
{
return control;
}
private DbControl()
{ }
public IDbInstance createInstance(string Name,string ConnectionString,string type)
{
string nspace = typeof(IDbInstance).Namespace;
Type t = Type.GetType(nspace + "." + type);
object obj = Activator.CreateInstance(t, new object[] { Name, pro, ConnectionString }); IDbInstance instance = obj as IDbInstance; Server.Add(Name, instance); return instance;
} public IDbInstance this[string Name]
{
get
{
if (Server.ContainsKey(Name))
return Server[Name];
else
return null;
}
}
}
}

这里算是顶层的类,最主要就是存放数据库和缓存对象。也许会好奇如果存放数据库,还可以理解,但是放着模型对象的缓存,这是为什么?因为在字符连接,还有具体执行数据库语句时候都会使用到。而且,不仅这个数据库,别的数据库也会使用到,虽然在一个大项目可能用多个数据库,但是他们使用到项目里的模型是一致的吧,因此,将缓存设置在这里,最好不过。而且整个框架只有这一份,其他地方注入使用,就不会耗内存了。

最后就是用户使用的部分,这部分已经屏蔽掉许多底层的部分,只留下通用方法。这些都已经封装好了,直接在这里调用就可以。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data; namespace Dal
{
public class DbHelper
{
private IDbInstance instance;
private string Name;
private DbControl control;
private IDbCode Code; public DbHelper()
{
control = DbControl.getInstance();
} public DbHelper createConnection(string Name, string ConnectionString, string type)
{
this.Name = Name;
instance = control.createInstance(Name, ConnectionString, type);
return this;
} public DbHelper ExcuteString(Func<IDbCode,IDbCode> Fun)
{
Code = Fun(this.instance.Code);
return this;
} public DbHelper createTransation(string Name)
{
this.instance.Excute.BeginTransation(Name);
return this;
} public DbHelper Rollback()
{
this.instance.Excute.RollBack();
return this;
}
public DbHelper Commit()
{
this.instance.Excute.Commit();
return this;
} public T ToModel<T>(CommandType Type = CommandType.Text)
where T:class,new()
{
if (this.Code == null)
return null;
return this.instance.Excute.ToModel<T>(this.Code,Type);
}
List<T> ToList<T>(CommandType Type = CommandType.Text)
where T:class,new()
{
if (this.Code == null)
return null;
return this.instance.Excute.ToList<T>(this.Code, Type);
}
object ToResult(CommandType Type = CommandType.Text)
{
if (this.Code == null)
return null;
return this.instance.Excute.ToResult(this.Code, Type);
}
int ExcuteResult(CommandType Type = CommandType.Text)
{
if (this.Code == null)
return -1;
return this.instance.Excute.ExcuteResult(this.Code, Type);
}
DataTable ToDataTable(CommandType Type = CommandType.Text)
{
if (this.Code == null)
return null;
return this.instance.Excute.ToDataTable(this.Code, Type);
}
DataSet ToDataSet(CommandType Type = CommandType.Text)
{
if (this.Code == null)
return null;
return this.instance.Excute.ToDataSet(this.Code, Type);
}
}
}

  结束:快要熄灯了,没办法在写文章。如果大家对框架有什么不明白,可以在下面评论区问我。这就是更新之后的框架,我觉得还是蛮好用的,虽然还没经过严密的检测。有什么问题,大家也可以指导下,我也在学习中~

C# .NET数据库操作的更多相关文章

  1. 如何在高并发环境下设计出无锁的数据库操作(Java版本)

    一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...

  2. 【知识必备】ezSQL,最好用的数据库操作类,让php操作sql更简单~

    最近用php做了点小东东,用上了ezSQL,感觉真的很ez,所以拿来跟大家分享一下~ ezSQL是一个非常好用的PHP数据库操作类.著名的开源博客WordPress的数据库操作就使用了ezSQL的My ...

  3. MySQL 系列(二) 你不知道的数据库操作

    第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 本章内容: 查看\创建\使用\删除 数据库 用户管理及授权实战 局域网 ...

  4. ABP创建数据库操作步骤

    1 ABP创建数据库操作步骤 1.1 SimpleTaskSystem.Web项目中的Web.config文件修改数据库配置. <add name="Default" pro ...

  5. 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  6. django数据库操作和中间件

    数据库配置 django的数据库相关表配置在models.py文件中,数据库的连接相关信息配置在settings.py中 models.py相关相关参数配置 from django.db import ...

  7. [Android Pro] 完美Android Cursor使用例子(Android数据库操作)

    reference to : http://www.ablanxue.com/prone_10575_1.html 完美 Android Cursor使用例子(Android数据库操作),Androi ...

  8. phpcms v9 中的数据库操作函数

    1.查询 $this->select($where = '', $data = '*', $limit = '', $order = '', $group = '', $key='')   返回 ...

  9. Android打造属于自己的数据库操作类。

    1.概述 开发Android的同学都知道sdk已经为我们提供了一个SQLiteOpenHelper类来创建和管理SQLite数据库,通过写一个子类去继承它,就可以方便的创建.管理数据库.但是当我们需要 ...

  10. python之数据库操作

    数据库操作 Python 操作 Mysql 模块的安装 1 2 3 4 5 linux:     yum install MySQL-python   window:     http://files ...

随机推荐

  1. cmake配置c++可调用的文件路径参数

    一.目的 在程序中使用一个路径配置,因为在svn服务器的测试数据,测试数据成为了本地路径,在程序中使用了绝对路径来处理文件的输入,这个令人头疼啊. 每次下完代码,我得挨个地方去找,谁在用本地路径,有点 ...

  2. WCF 设计和实现服务协定(01)

    作者:jiankunking 出处:http://blog.csdn.net/jiankunking WCF 术语: • 消息 – 消息是一个独立的数据单元,它可能由几个部分组成,包含消息正文和消息头 ...

  3. 【Redis学习】:Windows环境下的Redis安装与配置

    Redis简介 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C ...

  4. java中关于File类的mkdirs()和FIle()构造方法在windows环境内网测试总结

    环境:环境是内网windows,传入路径的时候不带盘符,并且服务器的win10也不是超级管理员账户 关于File类的mkdirs()远程访问创建不了文件和路径的问题. 如果浏览器操作者是windows ...

  5. 阿里巴巴fastjson的使用

    一.项目结构 一个学生类.当中学生类中能够包括Course类对象 使用Maven管理项目的能够加入fastjson的坐标: <dependency> <groupId>com. ...

  6. echarts怎么使用(最最最最简单版)(本质canvas)

    echarts怎么使用(最最最最简单版)(本质canvas) 一.总结 一句话总结:外部扩展插件肯定要写js啊,不然数据怎么进去,不然宽高怎么设置.本质都是canvas嵌套在页面上,比如div中. 1 ...

  7. JM-1 手机网站开发测试环境搭建

    JM-1 手机网站开发测试环境搭建 一.总结 一句话总结:WEB服务器环境可实现局域网内轻松访问.360wifi可以实现局域网. 二.微网站开发环境: 1.把微网站放到本机wamp环境下,用pc浏览器 ...

  8. 【hdu 1517】A Multiplication Game

    Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...

  9. sql中group by用来干嘛的

    sql中group by用来干嘛的 一.总结 一句话总结: 1.group by用来分类汇总的,by后面接要分的类 2.group by既然是分类汇总,那就要和聚合函数结合使用,因为要汇总啊 3.ha ...

  10. 小强的HTML5移动开发之路(40)——jqMobi中实践header定义的几种方式

    一.定义全局的header 这个header是所有panel默认的header,需要在<div id="afui">内部,也就是和<div id="co ...