简介
前阵子我变得沮丧的。NET中没有按锟t提供任何与事实查询数据库,它小于约8条线路的方法。我每次想要使数据库查询,甚至运行在SQL存储过程,我发现了它不可能没有至少3套波浪括号。首先,我打开SQL连接,然后我创建的SQL命令,然后使用数据读取器通过数据运行和得到什么我想它。所有的地方我的代码有这样的结构:List<string> result = new List<string>();
using (SqlConnection cn = new SqlConnection("Data Source=DatabaseServer;
Initial Catalog=Database;
User ID=UserID;Password=Password")) {
cn.Open();
using (SqlCommand cm = cn.CreateCommand()) {
cm.CommandText = "mystoredproc";
cm.CommandType = CommandType.StoredProcedure;
cm.Parameters.AddWithValue("@param1", "1");
cm.Parameters.AddWithValue("@param2", "2");
using (SqlDataReader dr = cm.ExecuteReader()) {
if (dr.HasRows) {
while (dr.Read()) {
result.Add(dr.GetString(0));
}
}
}
}
}
return result;
这样写的东西,可以得到很乏味,虽然我有一种倾向,很快类型,这仍然成为不外乎死记硬背浪费更多的时间。在努力解决这个问题,我创建了两班SqlReader和SQLData。这两个类是可序列化的。SqlReader类
SqlReader类可以执行查询,使用存储过程和文本的命令类型。区分用户在查询字符串中的空间很简单锟s意向。如果有一个,然后锟s文本的CommandType,如果有锟s没有,那么它锟s存储过程。
类创建一个静态构造函数如下:
{C}
它有两个参数,第一个SQL连接字符串,第二个是实际的查询。如果这是一个存储过程,然后查询可能如下所示:
SqlReader sr = SqlReader.Create("Data Source=DatabaseServer;Initial Catalog=Database;
User ID=UserID;Password=Password", "mystoredproc");
再次SqlReader类本身是不够聪明,发现您是否要执行一个存储过程或文本命令。构造函数看起来像这样的代码:
/// <summary>
/// Creates a SqlReader object with CommandType of Text
/// </summary><
/span>
/// <param name="connectionString">The connection string to use to connect to
/// the server.>/param>
/// <param name="commandText">The text to execute on the SQL server.>/param>
public static SqlReader Create(string connectionString, string commandText) {
SqlReader sr = new SqlReader();
sr._connectionString = connectionString;
sr._commandText = commandText;
if (commandText.Trim().Contains(" "))
sr._commandType = CommandType.Text;
else
sr._commandType = CommandType.StoredProcedure;
return sr;
}
注意,CommandType设置查询文本的基础上。如果有锟s一个空格,然后的CommandType是文字,如果没有空间,然后键入命令是一个存储过程。
让锟s说,你需要添加参数的存储过程。下面将做的伎俩:
SqlReader sr = SqlReader.Create("Data Source=DatabaseServer;Initial Catalog=Database;
User ID=UserID;Password=Password", "mystoredproc")
.AddParam("@param1", "1").AddParam("@param2", "2");
现在我们锟v个人增加了两个参数,我们的查询,第一个是@ param1和第二@ param2的。每个AddParam方法返回一个新的SqlReader对象,所以在这个过程中有一个递归排序,将填补参数。使用这个系统,可以无限数量的参数添加到查询。
现在执行的。有两种方法执行的executeQuery()的ExecuteNonQuery()。这些对应于SqlCommand类的同名方法。唯一不同的是,现在的executeQuery()返回一个SQLDATA类的ExecuteNonQuery(),而仅仅是一个void。
SqlData sd = SqlReader.Create("Data Source=DatabaseServer;Initial Catalog=Database;
User ID=UserID;Password=Password", "mystoredproc")
.AddParam("@param1", "1").AddParam("@param2", "2")
.Execute();
请注意,我锟v个人改变的类型我们新创建的变量到SQLDATA类型,这是因为Execute()方法返回一个SQLData对象,而不是一个SqlReader对象。这是很重要的原因有几个,但被人理解,我要解释SQLData的类。SQLData的类从SQL查询中的每一行存储在一个SqlRow的类,它维护的价值观和每行的列名。这些行的集合,使得SQLData的类。 SQLData的类的几种方法获取值,其中有几个重载:GetValueList,GetStringList,GetInt32List,GetInt64List,GetValue的,ISNULL的GetString,GetInt32等和GetInt64。 list命令将列名或0的列ID,将返回一个列表内,特别是列的所有值。这是伟大的迭代循环。我有看起来类似下列的代码:
foreach (string s in SqlReader.Create("Data Source=DatabaseServer;
Initial Catalog=Database;User ID=UserID;Password=Password",
"mystoredproc").AddParam("@param1", "1").AddParam("@param2", "2")
.Execute().GetStringList(0))
Console.WriteLine(s);
这将写入控制台从最左边的一列的每一个字符串返回执行mystoredproc @ PARAM1设置为1,@ param2的设置为2。
的方法,唐锟t重载四种方式返回一个列表。前两个重载唐锟t表示成一排,将始终返回值,从查询返回的第一行。他们可以被称为通过指定的列数或列名。第二个两个重载请致电1 -行数,行和列名或列号。这样,可用于其他迭代。
SqlReader类的心脏 - 查询
static void Main(string[] args) {
SqlData sd =SqlReader.Create("Data Source=DatabaseServer;Initial Catalog=Database;
User ID=UserID;Password=Password", "mystoredproc")
.AddParam("@param1", "1").AddParam("@param2", "2")
.Execute();
for (int i = 1; i < sd.RowCount; i++) {
Console.WriteLine(string.Format("Data from column 1: {0},
Data from column 2: {1}", sd.GetString(i, 0),
sd.GetString(i, 1)));
}
}
如果你锟v个人作出这一步,这里锟s有趣的东西。心脏SqlReader类的Execute方法。这是发生的所有有趣的工作。这里锟s的代码:
/// <summary>
/// Executes a query.
/// </summary><
/span>
public SqlData Execute() {
if (_hasRun)
_sqlData = new SqlData();
_hasRun = true;
if (string.IsNullOrEmpty(_connectionString))
throw new Exception("Morton's Common Tasks - SqlReader -
No Connection String Entered");
if (string.IsNullOrEmpty(_commandText))
throw new Exception("Morton's Common Tasks - SqlReader -
No Command to Perform");
using (SqlConnection cn = new SqlConnection(_connectionString)) {
cn.Open();
using (SqlCommand cm = cn.CreateCommand()) {
cm.CommandType = _commandType;
cm.CommandText = _commandText;
foreach (KeyValuePair<string, object> kvp in _parameters)
cm.Parameters.AddWithValue(kvp.Key, kvp.Value);
if (_returnData) {
using (SqlDataReader dr = cm.ExecuteReader()) {
if (dr.HasRows) {
while (dr.Read()) {
SqlRow sqlRow = new SqlRow();
for (int i = 0; i < dr.FieldCount; i++) {
if (string.IsNullOrEmpty(dr.GetName(i)))
sqlRow.AddSqlData("column_" + i.ToString(),
dr.GetValue(i));
else
sqlRow.AddSqlData(dr.GetName(i).ToLower(),
dr.GetValue(i));
}
_sqlData.Add(sqlRow);
}
}
}
} else {
cm.ExecuteNonQuery();
}
}
}
return this.Result;
}
的行的第一对夫妇检查,看看如果查询运行或不。如果有,那么我们需要重新设置将返回的值。我们将抛出一个例外,如果我们的查询和连接字符串是空的,然后我们锟l升开始查询。
首先,我们使用连接字符串连接到服务器,并打开连接。命令类型和命令文本设置。在此之后,参数添加到命令。
_returnData变量默认为true,并可以设置虚假的ExecuteNonQuery()方法,如果它被称为。如果_returnData是真的,那么我们将寻找一个结果。如果我们,然后我们创建一个SqlDataReader对象,并添加我们到SqlRow的所有数据,那么我们所有的行SQLData对象。如果有锟s没有名称的列,那么列名是编程方式设置一个任意值。在这种情况下,,将它们设置column_1,column_2等???如果有一个列名,然后用于实际的列名。
最后,在结束,结果将被返回。行锟return this.Result??使用下面的属性返回的_sqlData对象。
结论
/// <summary>
/// An object returning the result of a Sql Query.
/// </summary><
/span>
public SqlData Result {
get {
return _sqlData;
}
}
我锟v个人一直使用这个类在某些产品级应用现在一段时间没有问题,它已经救了我的时间在查询建设的巨大金额。
随意使用此代码。让我知道它是如何工作的!