异步的 SQL 数据库封装(1)
来源: 阅读:1217 次 日期:2015-08-31 15:37:13
温馨提示: 小编为您整理了“异步的 SQL 数据库封装(1)”,方便广大网友查阅!

引言

我一直在寻找一种简单有效的库,它能在简化数据库相关的编程的同时提供一种异步的方法来预防死锁。

我找到的大部分库要么太繁琐,要么灵活性不足,所以我决定自己写个。

使用这个库,你可以轻松地连接到任何 SQL-Server 数据库,执行任何存储过程或 T-SQL 查询,并异步地接收查询结果。这个库采用 C# 开发,没有其他外部依赖。

背景

你可能需要一些事件驱动编程的背景知识,但这不是必需的。

使用

这个库由两个类组成:

BLL (Business Logic Layer) 提供访问MS-SQL数据库、执行命令和查询并将结果返回给调用者的方法和属性。你不能直接调用这个类的对象,它只供其他类继承.

DAL (Data Access Layer) 你需要自己编写执行SQL存储过程和查询的函数,并且对于不同的表你可能需要不同的DAL类。

首先,你需要像这样创建 DAL 类:

namespace SQLWrapper

{

public class DAL : BLL

{

public DAL(string server, string db, string user, string pass)

{

base.Start(server, db, user, pass);

}

~DAL()

{

base.Stop(eStopType.ForceStopAll);

}

///////////////////////////////////////////////////////////

// TODO: Here you can add your code here...

}

}

由于BLL类维护着处理异步查询的线程,你需要提供必要的数据来拼接连接字符串。千万别忘了调用`Stop`函数,否则析构函数会强制调用它。

NOTE:如果需要连接其他非MS-SQL数据库,你可以通过修改BLL类中的`CreateConnectionString`函数来生成合适的连接字符串。

为了调用存储过程,你应该在DAL中编写这种函数:

public int MyStoreProcedure(int param1, string param2)

{

// 根据存储过程的返回类型创建用户数据

StoredProcedureCallbackResult userData = new StoredProcedureCallbackResult(eRequestType.Scalar);

// 在此定义传入存储过程的参数,如果没有参数可以省略 <span style="line-height:1.5;font-size:9pt;">userData.Parameters = new System.Data.SqlClient.SqlParameter[] { </span>

new System.Data.SqlClient.SqlParameter("@param1", param1),

new System.Data.SqlClient.SqlParameter("@param2", param2),

};

// Execute procedure...

if (!ExecuteStoredProcedure("usp_MyStoreProcedure", userData))

throw new Exception("Execution failed");

// 等待执行完成...

// 等待时长为 <userdata.tswaitforresult>

// 执行未完成返回 <timeout>

if (WaitSqlCompletes(userData) != eWaitForSQLResult.Success)

throw new Exception("Execution failed");

// Get the result...

return userData.ScalarValue;

}

正如你所看到的,存储过程的返回值类型可以是`Scalar`,`Reader`和`NonQuery`。对于 `Scalar`,`userData`的`ScalarValue`参数有意义(即返回结果);对于`NonQuery`,`userData`的 `AffectedRows`参数就是受影响的行数;对于`Reader`类型,`ReturnValue`就是函数的返回值,另外你可以通过 `userData`的`resultDataReader`参数访问recordset。

再看看这个示例:

public bool MySQLQuery(int param1, string param2)

{

// Create user data according to return type of store procedure in SQL(这个注释没有更新,说明《注释是魔鬼》有点道理)

ReaderQueryCallbackResult userData = new ReaderQueryCallbackResult();

string sqlCommand = string.Format("SELECT TOP(1) * FROM tbl1

WHERE code = {0} AND name LIKE &apos;%{1}%&apos;", param1, param2);

// Execute procedure...

if (!ExecuteSQLStatement(sqlCommand, userData))

return false;

// Wait until it finishes...

// Note, it will wait (userData.tsWaitForResult)

// for the command to be completed otherwise returns <timeout>

if (WaitSqlCompletes(userData) != eWaitForSQLResult.Success)

return false;

// Get the result...

if(userData.resultDataReader.HasRows && userData.resultDataReader.Read())

{

// Do whatever you want....

int field1 = GetIntValueOfDBField(userData.resultDataReader["Field1"], -1);

string field2 = GetStringValueOfDBField(userData.resultDataReader["Field2"], null);

Nullable<datetime> field3 = GetDateValueOfDBField(userData.resultDataReader["Field3"], null);

float field4 = GetFloatValueOfDBField(userData.resultDataReader["Field4"], 0);

long field5 = GetLongValueOfDBField(userData.resultDataReader["Field5"], -1);

}

userData.resultDataReader.Dispose();

return true;

}

在这个例子中,我们调用 `ExecuteSQLStatement` 直接执行了一个SQL查询,但思想跟 `ExecuteStoredProcedure` 是一样的。

我们使用 `resultDataReader` 的 `.Read()` 方法来迭代处理返回的结果集。另外提供了一些helper方法来避免叠代中由于NULL字段、GetIntValueOfDBField 等引起的异常。

更多信息请查看数据库
手机网站地址:异步的 SQL 数据库封装(1)
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map