Sofire v1.0 开源——快速数据库访问模式 Sofire.Data(2)
作者:互联网
那么,Sofire.v1.0包含什么内容?
下载地址:Sofire.v1.0-1206041、数据库访问(Sofire.Data)
2、快速动态反射(Sofire.Dynamic)
3、高效简短的二进制序列化(Sofire.Serialization.BinarySuite)
4、远程对象模式(Sofire.DataComm.Remote)
5、安全高效Socket(Sofire.DataComm.Net)
6、面向切面(Sofire.AOP)
7、等。由于Sofire v1.0 第一期移植,故而功能暂时尚未全部移植完成。
前文紧接上篇内容《Sofire v1.0 开源——WinForm/SL/WebForm 的 Remoting(1)》。
本文主要讲述 SOFIRE 框架在底层开发中,采用 Sofire.Data 对各种数据库的操作进行统一使用。它仿佛就是对 ADO.NET 的全面封装。
当然,Sofire.Data 支持哪些数据库,关键是在于实现,而不是在于“支持不支持”,理论上所有基于 ADO.NET 的数据库全部支持,而其他数据库,也有部分支持。
当前所支持的数据库包括:MSSQL、Oracle、Oracle、DDTekOracle、OleDb 和 SQLite。至于其他的数据库(如 MySql),由于本人实际项目中并没使用这些数据库,所有暂时不支持,如果你想支持其他数据库,请继承 Sofire.Data.QueryEngineBase。
框架约定 任何函数具有返回内容 在框架的开发过程中,在所有公共函数,都应具有一个返回描述。例如,在处理某业务的函数,可能有人会这样写: public DataTable GetTotalReport(string username, DateTime begin, DateTime end)
{
//处理过程...
return new DataTable();
}
当然,这并不是指责这样的写法的好坏,而是建议对函数的返回值进行适当的封装描述。例如,我可以这样:
public Result<DataTable> GetTotalReport(string username, DateTime begin, DateTime end)
{
try
{
//处理过程...
return new DataTable();
}
catch(Exception ex)
{
return ex;
}
}
通过这样的约定,可以明确的告诉函数调用者,这个函数返回一个值,但这个操作函数也可能会返回一个错误的内容。
返回描述,是为了更好的处理当遇到具有返回内容的操作函数时,可以这样的处理返回结果
public void Test()
{
var r = this.GetTotalReport("a", DateTime.Now, DateTime.Now);
if(r.IsSucceed)
{
DataTable table = r.Value;
}
else
{
Exception ex = r.Exception;
}
}
简单的代码,表述了返回值具备了函数操作结果的“正确性”,同时也提供了错误的详细信息。以下是返回结果的接口(IResult):
/// <summary>
/// 表示一个结果(接口)。
/// </summary>
public interface IResult
{
#region Properties
/// <summary>
/// 获取执行时发生的错误。
/// </summary>
Exception Exception
{
get;
}
/// <summary>
/// 获取一个值,表示执行结果是否为失败。
/// </summary>
bool IsFailed
{
get;
}
/// <summary>
/// 获取一个值,表示执行结果是否为忽略。
/// </summary>
bool IsIgnored
{
get;
}
/// <summary>
/// 获取一个值,表示执行结果是否为成功。
/// </summary>
bool IsSucceed
{
get;
}
/// <summary>
/// 获取执行的状态。
/// </summary>
ResultState State
{
get;
}
#endregion Properties
#region Methods
/// <summary>
/// 指定错误信息,将当前结果切换到失败的状态。
/// </summary>
void ToFailded(Exception exception);
/// <summary>
/// 指定错误信息,将当前结果切换到失败的状态。
/// </summary>
void ToFailded(string exceptionMessage);
/// <summary>
/// 将当前结果切换到忽略的状态。
/// </summary>
void ToIgnored();
/// <summary>
/// 将当前结果切换到成功的状态,并且清除结果的错误信息。
/// </summary>
void ToSuccessed();
/// <summary>
/// 指示一个结果,与当前结果进行校验。如果 <paramref name="result"/> 是一个错误结果,那么当前的结果将会转换为错误状态。否则将会转换 <paramref name="result"/> 的状态。
/// </summary>
/// <param name="result">比较的结果。</param>
/// <returns>返回一个值,表示结果是否为成功状态。</returns>
bool Checking(Result result);
#endregion Methods
}
/// <summary>
/// 表示包含一个返回值的结果(接口)。
/// </summary>
/// <typeparam name="TValue">返回值的类型。</typeparam>
public interface IResult<TValue> : IResult
{
#region Properties
/// <summary>
/// 设置或获取结果的返回值。若结果不处于成功的状态,将返回默认值。
/// </summary>
TValue Value
{
get; set;
}
#endregion Properties
#region Methods
/// <summary>
/// 将当前结果切换到成功的状态,并且清除结果的错误信息。
/// </summary>
/// <param name="value">结果返回的值。</param>
void ToSuccessed(TValue value);
/// <summary>
/// 指示一个结果,与当前结果进行校验。如果 <paramref name="result"/> 是一个错误结果,那么当前的结果将会转换为错误状态。否则将会转换 <paramref name="result"/> 的状态。
/// </summary>
/// <param name="result">比较的结果。</param>
/// <param name="value">状态为成功时的返回值。</param>
/// <returns>返回一个值,表示结果是否为成功状态。</returns>
bool Checking(Result result, TValue value);
#endregion Methods
}
/// <summary>
/// 表示包含两个返回值的结果(接口)。
/// </summary>
/// <typeparam name="TValue1">第一个返回值的类型。</typeparam>
/// <typeparam name="TValue2">第二个返回值的类型。</typeparam>
public interface IResult<TValue1, TValue2> : IResult
{
#region Properties
/// <summary>
/// 设置或获取结果的第一个返回值。若结果不处于成功的状态,将返回默认值。
/// </summary>
TValue1 Value1
{
get; set;
}
/// <summary>
/// 设置或获取结果的第二个返回值。若结果不处于成功的状态,将返回默认值。
/// </summary>
TValue2 Value2
{
get; set;
}
#endregion Properties
#region Methods
/// <summary>
/// 将当前结果切换到成功的状态,并且清除结果的错误信息。
/// </summary>
/// <param name="value1">结果的第一个返回值。</param>
/// <param name="value2">结果的第二个返回值。</param>
void ToSuccessed(TValue1 value1, TValue2 value2);
/// <summary>
/// 指示一个结果,与当前结果进行校验。如果 <paramref name="result"/> 是一个错误结果,那么当前的结果将会转换为错误状态。否则将会转换 <paramref name="result"/> 的状态。
/// </summary>
/// <param name="result">比较的结果。</param>
/// <param name="value1">状态为成功时的第一个返回值。</param>
/// <param name="value2">状态为成功时的第二个返回值。</param>
/// <returns>返回一个值,表示结果是否为成功状态。</returns>
bool Checking(Result result, TValue1 value1, TValue2 value2);
#endregion Methods
}
Sofire.Data 数据库是如何连接的?
Sofire.Data 的所有数据库实现,都派生于 Sofire.Data.QueryEngineBase,通过简单的几个抽象实现,从而达到对数据库的快速支持。
public void DataConnect()
{
string connectionString = "";
OracleQuery oracleQuery = new OracleQuery(connectionString); // 微软已经不建议使用这种方式连接 Oracle
DDTekOracleQuery oleDbQuery = new DDTekOracleQuery(connectionString);
MsSqlQuery mssqlQuery = new MsSqlQuery(connectionString);
OleDbQuery oleDbQuery = new OleDbQuery(connectionString);
SQLiteQuery sqliteQuery = new SQLiteQuery(connectionString);
// 派生基类 QueryEngineBase 扩展,可以对更多的数据库提供支持。
}
数据库是如何查询的?
数据库的查询
public void Execute()
{
string connectionString = "";
int uid = 1;
DDTekOracleQuery oracleQuery = new DDTekOracleQuery(connectionString);
TableResult r1 = oracleQuery.ExecuteTable("SELECT * FROM Users WHERE UID=:uid", "uid", uid);
if(r1.IsSucceed)
{
DataTable table = r1.Value;
}
SqlQuery mssqlQuery = new SqlQuery(connectionString);
TableResult r2 = mssqlQuery.ExecuteTable("SELECT * FROM Users WHERE UID=@uid", "@uid", uid);
if(r2.IsSucceed)
{
DataTable table = r2.Value;
}
}
当然,上面的演示代码仅仅是返回一张表,更多的支持请参考以下图片
由于今年的工作关系,我对 Oracle 的接触频繁,Sofire.Data 中对于 Oracle 的支持,也逐渐成熟中,例如支持多行 ExecuteNoQuery,支持游标参数。
private Result Test1()
{
//“>”符号表示这是一个存储过程,或程序包
// PKG_FLOW_NAME.UP_GetFlowNameById 的返回值在于一个游标参数。
var tableResult = query.ExecuteTable(">PKG_FLOW_NAME.UP_GetFlowNameById"
, new ExecuteParameter("v_FID", 111, DbType.VarNumeric)
, query.CreateCursor("c"));
if(tableResult.IsSucceed)
{
Console.WriteLine(tableResult.Value.Rows.Count);
}
return tableResult;
}
private Result Test2()
{
var noQueryResult = query.ExecuteNoQuery(@"begin
insert into table1 select * from XXX;
insert into table2 select * from XXX;
insert into table3 select * from XXX;
insert into table4 select * from XXX;
end;");
if(tableResult.IsSucceed)
{
Console.WriteLine(tableResult.Value.Rows.Count);
}
return tableResult;
}
结束语
由于时间的关系(最近工作岗位变动),最重要,也是这套框架元老级组件——数据库部分,介绍的并不详细。接下来,可能对 Sofire.Data 的高级部分进行讲解,比如对查询前后的事件支持,查询结果自动转换为对象/集合。不过这种比较代码性的东西,的确比较难阅读,也让我异常纠结。
额,好像很多人想觉得我这款博客皮肤不错?其实这一款博客皮肤是参考 李宝亨达人 的博客风格进行改版的,很感谢他的皮肤(他是绿色版,我是蓝色版)。
我很懒,但如果您在使用这套组件中遇见任何问题或者有任何建议意见,可以在博客留言,我将会及时回复。源码已更新。稍后上传。
转载于:https://www.cnblogs.com/sofire/archive/2012/06/04/2513867.html
标签:状态,结果,数据库,v1.0,Sofire,new,返回值,Data 来源: https://blog.csdn.net/weixin_34318326/article/details/94147962