一、Topshelf基本配置
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Topshelf;
namespace MealTimer
{
public class Program
{
public static void Main()
{
HostFactory.Run(x => //這裏通過HostFactory.Run安裝這個host,通過其lambda表達式的x來進行各種host級別的參數配置。
{
x.Service<MealTimer>(s => //這裏我們告訴Topshelf這裏有一個‘TownCrier’服務,lambda表達式的s用於設置各種服務級別的配置。
{
s.ConstructUsing(name => new MealTimer()); //這裏告訴Topshelf如何給這個服務構建一個實例,這裏我們只是簡單的將實例new出來,實際使用中通常會通過IoC來注入一個實例,代碼類似‘container.GetInstance<TownCrier>()’.
s.WhenStarted(tc => tc.Start()); //告訴Topshelf啓動這個服務時做什麼。
s.WhenStopped(tc => tc.Stop()); //告訴Topshelf如何停止這個服務時做什麼。
});
//以本地帳戶身份運行,這裏選擇的是登錄爲:本地系統local system
x.RunAsLocalSystem();
x.SetDescription("內部系統自動添加報餐表"); //設置該服務的描述
x.SetDisplayName("CanYouAddmealService"); //設置該服務的顯示名稱。
x.SetServiceName("CanYouAddmealService"); //設置該服務自身的名字,即服務名稱。
//服務啓動模式
x.StartAutomatically(); //自動
x.EnableServiceRecovery(rc => rc.RestartService(1));// 服務如果意外停止,1分鐘後恢復啓動
});
}
}
}
二、配置Start方法
public void Start()
{
Thread sendThread = new Thread(new ThreadStart(delegate()
{
try
{
while (true)
{
if (IsDBOnline())
{
AddMealSet();
}
else
{
Thread.Sleep(60 * 60 * 1000);
SaveRecord("\r\n" + "數據庫鏈接失敗,線程休眠【" + 60 + "】分鐘。");
}
}
}
catch (Exception ex)
{
SaveRecord("\r\n" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n" + ex);
//線程終止,只能在該線程的內部終止,不能寫在線程類的外部
Thread.CurrentThread.Abort();
}
}));
//啓動線程
sendThread.Start();
//指定後臺線程
sendThread.IsBackground = true;
}
在Start方法裏面,定義一個while(true)的死循環,死循環裏面執行一次添加方法,就定時休眠,在執行添加方法前,先檢測一下數據庫連接狀態,如果暫時連接失敗,等60分鐘後再啓動服務。
/// <summary>
/// 數據庫是否在線
/// </summary>
/// <returns></returns>
public bool IsDBOnline()
{
string connString = ConfigurationSettings.AppSettings["MsSql"];
SqlConnection Connection = new SqlConnection(connString);
try
{
Connection.Open();
}
catch (Exception ex)
{
SaveRecord("\r\n" + "數據庫鏈接錯誤:" + ex.ToString());
return false;
}
finally
{
Connection.Close();
}
return true;
}
三、定時添加數據方法
/// <summary>
/// 根據當前時間和系統設置時間對比,進行自動報餐處理
/// </summary>
public void AddMealSet()
{
while (true)//構建一個死循環,裏面只有線程休眠時間,到了時間重新判斷,無限循環執行
{
#region 參數配置
//取出配置文件的定時新增報餐數據
string AddTime = ConfigurationSettings.AppSettings["AddTime"];
//取出配置文件的星期值
string dayofweek = ConfigurationSettings.AppSettings["Day"];
//取出配置裏面的數據要放在while (true)循環裏面,放在外面,如果更新了配置文件,這些數據不能被讀取到,只能重新啓動才能讀取到最新
DateTime Day = DateTime.Now;//DateTime.Now要放在while (true)循環裏面,否則DateTime.Now永遠是第一次啓動時的時間,沒有更新
string MealAutoAddstring = MealAutoAdd.AddMeal(Day);// 根據時間判斷自動插入數據庫一條報餐表數據語句,返回語句
if (string.IsNullOrEmpty(AddTime))
{
throw new Exception("從App.config文件獲取定時發送短信時間AddTime報錯,線程已經退出,請排查錯誤後,重啓服務器。");
}
if (string.IsNullOrEmpty(MealAutoAddstring))
{
throw new Exception("報餐表數據語句,返回值爲空!");
}
int HHNow = Convert.ToInt32(Day.ToString("HH"));//定義現在時間小時數
int mmNow = Convert.ToInt32(Day.ToString("mm"));//定義現在時間分鐘數
int AddTime_Val = Convert.ToInt32(AddTime);//獲取添加報餐時間小時數
int _SleepTime = 0;
string monthfirstday = DateTime.Now.Date.ToString("dd");//獲取每月1號
#endregion
if (MealAutoAdd.Week(Day.DayOfWeek.ToString()) != dayofweek & MealAutoAdd.Week(Day.DayOfWeek.ToString()) != "星期二")//非週二、三時間,線程休眠24小時.
{
#region 非週二、三時間,線程休眠24小時
_SleepTime = 86400000;
if (monthfirstday == "01")
{
AddHumanCost();//每月1號,自動添加人力成本數據
}
SaveRecord("\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n" +
MealAutoAdd.Week(Day.DayOfWeek.ToString()) + ",線程休眠:" + 24 + "小時,共(毫秒):" + _SleepTime);
Thread.Sleep(_SleepTime);
#endregion
}
else if (MealAutoAdd.Week(Day.DayOfWeek.ToString()) == "星期二")//爲了避免在週二重啓服務器或服務重啓,如果休眠24小時,可能會錯過週三的報餐時間
{
#region 星期二,如果當前小時數小於0,則休眠時間可以是24小時,休眠結束之後,還在定時報餐時間範圍內
if (HHNow - AddTime_Val < 0)//如果當前小時數小於0,則休眠時間可以是24小時,休眠結束之後,還在定時報餐時間範圍內
{
if (monthfirstday == "01")
{
AddHumanCost();//每月1號,自動添加人力成本數據
}
_SleepTime = ((24 + AddTime_Val - HHNow - 1) * 60000 * 60) + (60 - mmNow) * 60000;//當前時間 如果是7:45,休眠24小時之後,還是7:45,所以要加上15分鐘,正好8點
string SaveRecordstring = mmNow == 0
? "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n週二時間,當前時間在定時報餐之前,線程休眠:" +
(24 + AddTime_Val - HHNow) + "小時,共(毫秒):" + _SleepTime
: "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n週二時間,當前時間在定時報餐之前,線程休眠:" +
(24 + AddTime_Val - HHNow - 1) + "小時" + (60 - mmNow) +
"分鐘,共(毫秒):" + _SleepTime;
SaveRecord(SaveRecordstring);
Thread.Sleep(_SleepTime);
}
#endregion
#region 如果當前小時數大於0,則休眠時間不能是24小時,否則會造成休眠結束之後,錯過報餐時間
else if (HHNow - AddTime_Val > 0)//如果當前小時數大於0,則休眠時間不能是24小時,否則會造成休眠結束之後,錯過報餐時間
{
if (monthfirstday == "01")
{
AddHumanCost();//每月1號,自動添加人力成本數據
}
_SleepTime = (24 - HHNow - 1) * 60000 * 60 + (60 - mmNow) * 60000;//當前時間 如果是9:45,需要休眠14:15小時之後,爲整點
string SaveRecordstring = mmNow == 0
? "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n週二時間,當前時間在定時報餐之後" + (HHNow - AddTime_Val) + "小時,線程休眠:" +
(24 - HHNow) + "小時,共(毫秒):" +
_SleepTime
: "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n週二時間,當前時間在定時報餐之後" + (HHNow - AddTime_Val) + "小時,線程休眠:" +
(24 - HHNow - 1) + "小時" + (60 - mmNow) + "分鐘,共(毫秒):" +
_SleepTime;
SaveRecord(SaveRecordstring);
Thread.Sleep(_SleepTime);
}
#endregion
#region 時間在當前時段,如果當前時間是整點數
else//時間在當前時段,如果當前時間是整點數
{
_SleepTime = 23 * 3600000 + (60 - mmNow) * 60000;//當前時間 如果是8:45,需要休眠23:15小時之後,爲整點
if (monthfirstday == "01")
{
AddHumanCost();//每月1號,自動添加人力成本數據
}
string SaveRecordstring = mmNow == 0
? "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n週二時間,當前時間在定時報餐之後" + (HHNow - AddTime_Val) + "小時,線程休眠:" + 24 +
"小時,共(毫秒):" + _SleepTime
: "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n週二時間,當前時間在定時報餐之後" + (HHNow - AddTime_Val) + "小時,線程休眠:" + 23 +
"小時" + (60 - mmNow) + "分鐘,共(毫秒):" + _SleepTime;
SaveRecord(SaveRecordstring);
Thread.Sleep(_SleepTime);
}
#endregion
}
else//當前時間爲週三時間
{
#region 當前時間爲週三時間,也就是報餐時間
if (DateTime.Now.ToString("HH") == AddTime & MealAutoAdd.Week(Day.DayOfWeek.ToString()) == dayofweek)//判斷是否到小時點,和對應的星期幾
{
//關鍵一步:不管服務器是否重新啓動,都要判斷數據是否已經添加過
string Holiday = MealAutoAdd.MealDay_1(Day);
if (Holiday == "" & !isAddMealSet())//先判斷是不是已經新增了節假日的報餐數據,再判斷是否新增週末報餐的數據
{
SqlHelper.GetSingle(MealAutoAddstring);
SqlHelper.GetSingle(
"INSERT INTO sys_Event (E_U_LoginName, E_DateTime,E_Record) VALUES ('報餐定時器', '" +
Day.ToString("yyyy-MM-dd HH:mm:ss") + "', '自動添加“" +
SqlHelper.GetSingle("SELECT TOP 1 MS_MealType FROM sys_MealSet order by MS_ID DESC") +
"”報餐數據')");
SaveRecord("\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n自動添加“" +
SqlHelper.GetSingle(
"SELECT TOP 1 MS_MealType FROM sys_MealSet order by MS_ID DESC") + "”報餐數據'");//記錄到本地日誌
AddMeal();//根據自動報餐設置,自動添加報餐記錄
}
if (Holiday != "" & !isHolidayAdd())//先判斷是不是已經新增了節假日的報餐數據,再判斷是否新增週末報餐的數據
{
SqlHelper.GetSingle(MealAutoAddstring);
SqlHelper.GetSingle(
"INSERT INTO sys_Event (E_U_LoginName, E_DateTime,E_Record) VALUES ('報餐定時器', '" +
Day.ToString("yyyy-MM-dd HH:mm:ss") + "', '自動添加“" +
SqlHelper.GetSingle("SELECT TOP 1 MS_MealType FROM sys_MealSet order by MS_ID DESC") +
"”報餐數據')");
SaveRecord("\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n自動添加“" +
SqlHelper.GetSingle(
"SELECT TOP 1 MS_MealType FROM sys_MealSet order by MS_ID DESC") + "”報餐數據'");
}
else//這個else裏面一定要進行休眠,否則在這一個小時之內無數次循環添加報餐數據
{
if (monthfirstday == "01")
{
AddHumanCost();//每月1號,自動添加人力成本數據
}
SaveRecord("\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n在自動報餐時間範圍內,已經進行報餐數據新增,線程休眠(分鐘):" + (60 - mmNow));
//注意此處不能終止循環,否則跳出循環,不能再次新增數據
Thread.Sleep((60 - mmNow) * 60000);
}
}
#endregion
#region 如果不是在報餐的正點數
else//如果不是在報餐的正點數
{
if (HHNow < AddTime_Val & MealAutoAdd.Week(Day.DayOfWeek.ToString()) == dayofweek)//判斷小時點,和對應的星期幾
{
_SleepTime = (AddTime_Val - HHNow - 1) * 60000 * 60 + (60 - mmNow) * 60000;//假如現在是7:45,,8點爲報餐整點,則休眠15分鐘即可
string SaveRecordstring = mmNow == 0
? "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n不在自動報餐時間範圍內,線程休眠:" + (AddTime_Val - HHNow) + "小時,共(毫秒):" + _SleepTime
: "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n不在自動報餐時間範圍內,線程休眠:" + (AddTime_Val - HHNow - 1) + "小時" +
(60 - mmNow) + "分鐘,共(毫秒):" + _SleepTime;
SaveRecord(SaveRecordstring);
if (monthfirstday == "01")
{
AddHumanCost();//每月1號,自動添加人力成本數據
}
Thread.Sleep(_SleepTime);//當天時間,時間小時數小於報餐小時數,休眠當前時間小時數和報餐時間點數的差值,例如:當前時間是7點,則休眠1個小時
}
if (HHNow > AddTime_Val & MealAutoAdd.Week(Day.DayOfWeek.ToString()) == dayofweek)//判斷是否到小時點,和對應的星期幾
{
_SleepTime = (24 - HHNow - 1) * 60000 * 60 + (60 - mmNow) * 60000;//假如現在是9:45,則休眠14:15分鐘,可到24整點
string SaveRecordstring = mmNow == 0
? "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n不在自動報餐時間範圍內,線程休眠:" + (24 - HHNow) + "小時,共(毫秒):" + _SleepTime
: "\r\n" + Day.ToString("yyyy-MM-dd HH:mm:ss") +
"\r\n不在自動報餐時間範圍內,線程休眠:" + (24 - HHNow - 1) + "小時" +
(60 - mmNow) + "分鐘,共(毫秒):" + _SleepTime;
SaveRecord(SaveRecordstring);//當天時間,時間小時數大於報餐小時數,休眠當天的剩餘小時數,例如:當前時間是9點,則休眠24-9=15個小時
if (monthfirstday == "01")
{
AddHumanCost();//每月1號,自動添加人力成本數據
}
Thread.Sleep(_SleepTime);
}
}
#endregion
}
}
}
四、自動添加報餐方法
/// <summary>
/// 添加報餐方法
/// </summary>
public void AddMeal()
{
DataTable dt = SqlHelper.QueryTable("SELECT * FROM sys_MealDefaultValues");
string MealName = ConfigurationSettings.AppSettings["MealName"];
string Password = ConfigurationSettings.AppSettings["Password"];
string host = ConfigurationSettings.AppSettings["host"];
for (int i = 0; i < dt.Rows.Count; i++)
{
int MS_ID = Convert.ToInt32(SqlHelper.GetSingle("SELECT TOP 1 MS_ID FROM sys_MealSet order by MS_ID DESC").ToString());
if (dt.Rows[i][1].ToString() == "0")//dt.Rows[i][1].ToString()
{
string M_UserID = dt.Rows[i][2].ToString();
string M_day_1_Lunch = dt.Rows[i][3].ToString();
string M_day_1_Dinner = dt.Rows[i][4].ToString();
string M_day_2_Lunch = dt.Rows[i][5].ToString();
string M_day_2_Dinner = dt.Rows[i][6].ToString();
string M_IsMail = dt.Rows[i][7].ToString();
string AddString =
"INSERT INTO sys_Meal (M_UserID, M_MS_ID,M_day_1_Lunch,M_day_1_Dinner,M_day_2_Lunch,M_day_2_Dinner) VALUES ('" +
M_UserID + "','" + MS_ID + "','" + M_day_1_Lunch + "','" + M_day_1_Dinner + "','" +
M_day_2_Lunch + "','" + M_day_2_Dinner + "')";
int info = SqlHelper.ExecuteSql(AddString);
#region 設置MealTo,Content
string MealTo =
SqlHelper.GetSingle("SELECT U_CompanyMail FROM sys_User where UserID='" + dt.Rows[i][2] + "'").ToString() !=
""
? SqlHelper.GetSingle("SELECT U_CompanyMail FROM sys_User where UserID='" + dt.Rows[i][2] + "'").ToString()
: SqlHelper.GetSingle("SELECT U_Email FROM sys_User where UserID='" + dt.Rows[i][2] + "'").ToString();
string Content = "尊敬的:" +
SqlHelper.GetSingle("SELECT U_LoginName FROM sys_User where UserID='" +
dt.Rows[i][2] + "'") + ",您的報餐情況爲:" +
DisabilityType_Value.GetSaturdayDate().ToString("yyyy-MM-dd-星期六") + "(上午:" +
dt.Rows[i][3].ToString().Substring(0, 2) + ",下午:" +
dt.Rows[i][4].ToString().Substring(0, 2) + ");" +
DisabilityType_Value.GetSaturdayDate().AddDays(1).ToString("yyyy-MM-dd-星期日") +
"(上午:" + dt.Rows[i][5].ToString().Substring(0, 2) + ",下午:" +
dt.Rows[i][6].ToString().Substring(0, 2) + ")。報餐郵件是否發送,現已可在系統中進行設置!";
#endregion
if (info != 0)
{
bool SentOrNot = M_IsMail == "1" ? SendEmail(MealTo, MealName, Password, host, Content) : false;
#region 發送郵件成功,則日誌記錄中顯示“併發送郵件成功”的字段,否則不顯示這幾個字
if (SentOrNot)//發送郵件成功,則日誌記錄中顯示“併發送郵件成功”的字段,否則不顯示這幾個字
{
SqlHelper.GetSingle(
"INSERT INTO sys_Event (E_U_LoginName, E_DateTime,E_Record) VALUES ('報餐定時器', '" +
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "', '自動添加“" +
SqlHelper.GetSingle("SELECT U_LoginName FROM sys_User where UserID='" + dt.Rows[i][2] +
"'") + "," +
SqlHelper.GetSingle("SELECT TOP 1 MS_MealType FROM sys_MealSet order by MS_ID DESC") +
"”的報餐數據,併發送郵件成功!')");
SaveRecord("\r\n" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n自動添加“" +
SqlHelper.GetSingle("SELECT U_LoginName FROM sys_User where UserID='" +
dt.Rows[i][2] + "'") + "," +
SqlHelper.GetSingle(
"SELECT TOP 1 MS_MealType FROM sys_MealSet order by MS_ID DESC") +
"”的報餐數據,併發送郵件成功!')");
}
#endregion
#region 發送郵件成功,則日誌記錄中顯示“併發送郵件成功”的字段,否則不顯示這幾個字
else
{
SqlHelper.GetSingle(
"INSERT INTO sys_Event (E_U_LoginName, E_DateTime,E_Record) VALUES ('報餐定時器', '" +
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "', '自動添加“" +
SqlHelper.GetSingle("SELECT U_LoginName FROM sys_User where UserID='" + dt.Rows[i][2] +
"'") + "," +
SqlHelper.GetSingle("SELECT TOP 1 MS_MealType FROM sys_MealSet order by MS_ID DESC") +
"”的報餐數據!')");
SaveRecord("\r\n" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n自動添加“" +
SqlHelper.GetSingle("SELECT U_LoginName FROM sys_User where UserID='" +
dt.Rows[i][2] + "'") + "," +
SqlHelper.GetSingle(
"SELECT TOP 1 MS_MealType FROM sys_MealSet order by MS_ID DESC") +
"”的報餐數據!')");
}
#endregion
}
}
}
}
五、發送郵件方法
/// <summary>
/// 發送郵件方法
/// </summary>
/// <param name="MealTo">郵件接收者的帳號</param>
/// <param name="MealUserName">註冊的郵箱</param>
/// <param name="MealPassword">郵箱密碼</param>
/// <param name="Host">郵箱對應的SMTP服務器</param>
/// <param name="Content">郵件內容</param>
/// <returns></returns>
public bool SendEmail(string MealTo, string MealUserName, string MealPassword, string Host, string Content)
{
MailMessage msg = new MailMessage();
msg.To.Add(MealTo);//郵件接收者的帳號
msg.From = new MailAddress(MealUserName, "殘友內部系統郵件", System.Text.Encoding.UTF8);//發送郵件的帳號及顯示名稱和字符編碼
msg.Subject = "殘友內部系統自動增加報餐數據信息";//郵件標題
msg.SubjectEncoding = System.Text.Encoding.UTF8;//郵件標題編碼
msg.Body = Content;//郵件內容
msg.BodyEncoding = System.Text.Encoding.UTF8;//郵件內容編碼
msg.IsBodyHtml = false;//是否是HTML郵件
msg.Priority = MailPriority.Normal;//郵件優先級
SmtpClient client = new SmtpClient();
client.Credentials = new System.Net.NetworkCredential(MealUserName, MealPassword);//註冊的郵箱和密碼,就QQ郵箱而言,如果設置了獨立密碼,要用獨立密碼代替密碼
client.Host = Host;//QQ郵箱對應的SMTP服務器
object userState = msg;
try
{
client.SendAsync(msg, userState);
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
六、SqlHelper類
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Collections;
using System.Data;
using System.Configuration;
using System.Web;
namespace FrameWork
{
public class SqlHelper
{
public static string connectionString = ConfigurationManager.ConnectionStrings["FrameWorkConnectionString"].ConnectionString;
public SqlHelper()
{
}
#region 公用方法
public static int GetMaxID(string FieldName, string TableName)
{
string strsql = "select max(" + FieldName + ")+1 from " + TableName;
object obj = SqlHelper.GetSingle(strsql);
if (obj == null)
{
return 1;
}
else
{
return int.Parse(obj.ToString());
}
}
public static bool Exists(string strSql)
{
object obj = SqlHelper.GetSingle(strSql);
int cmdresult;
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
cmdresult = 0;
}
else
{
cmdresult = int.Parse(obj.ToString());
}
if (cmdresult == 0)
{
return false;
}
else
{
return true;
}
}
public static bool Exists(string strSql, params SqlParameter[] cmdParms)
{
object obj = SqlHelper.GetSingle(strSql, cmdParms);
int cmdresult;
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
cmdresult = 0;
}
else
{
cmdresult = int.Parse(obj.ToString());
}
if (cmdresult == 0)
{
return false;
}
else
{
return true;
}
}
#endregion
#region 執行簡單SQL語句
/// <summary>
/// 執行SQL語句,返回影響的記錄數
/// </summary>
/// <param name="SQLString">SQL語句</param>
/// <returns>影響的記錄數</returns>
public static int ExecuteSql(string SQLString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(SQLString, connection))
{
try
{
connection.Open();
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SqlClient.SqlException E)
{
connection.Close();
throw new Exception(E.Message);
}
}
}
}
/// <summary>
/// 執行SQL語句,返回影響的記錄數 適用於select語句
/// </summary>
/// <param name="SQLString">SQL語句</param>
/// <returns>影響的記錄數</returns>
public static int ExecuteSql2(string SQLString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(SQLString, connection))
{
try
{
connection.Open();
int rows = Convert.ToInt32(cmd.ExecuteScalar());
return rows;
}
catch (System.Data.SqlClient.SqlException E)
{
connection.Close();
throw new Exception(E.Message);
}
}
}
}
/// <summary>
/// 執行多條SQL語句,實現數據庫事務。
/// </summary>
/// <param name="SQLStringList">多條SQL語句</param>
public static void ExecuteSqlTran(ArrayList SQLStringList)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
SqlTransaction tx = conn.BeginTransaction();
cmd.Transaction = tx;
try
{
for (int n = 0; n < SQLStringList.Count; n++)
{
string strsql = SQLStringList[n].ToString();
if (strsql.Trim().Length > 1)
{
cmd.CommandText = strsql;
cmd.ExecuteNonQuery();
}
}
tx.Commit();
}
catch (System.Data.SqlClient.SqlException E)
{
tx.Rollback();
throw new Exception(E.Message);
}
}
}
/// <summary>
/// 執行帶一個存儲過程參數的的SQL語句。
/// </summary>
/// <param name="SQLString">SQL語句</param>
/// <param name="content">參數內容,比如一個字段是格式複雜的文章,有特殊符號,可以通過這個方式添加</param>
/// <returns>影響的記錄數</returns>
public static int ExecuteSql(string SQLString, string content)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(SQLString, connection);
System.Data.SqlClient.SqlParameter myParameter = new System.Data.SqlClient.SqlParameter("@content", SqlDbType.VarChar);
myParameter.Value = content;
cmd.Parameters.Add(myParameter);
try
{
connection.Open();
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SqlClient.SqlException E)
{
throw new Exception(E.Message);
}
finally
{
cmd.Dispose();
connection.Close();
}
}
}
/// <summary>
/// 向數據庫裏插入圖像格式的字段(和上面情況類似的另一種實例)
/// </summary>
/// <param name="strSQL">SQL語句</param>
/// <param name="fs">圖像字節,數據庫的字段類型爲image的情況</param>
/// <returns>影響的記錄數</returns>
public static int ExecuteSqlInsertImg(string strSQL, byte[] fs)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(strSQL, connection);
System.Data.SqlClient.SqlParameter myParameter = new System.Data.SqlClient.SqlParameter("@fs", SqlDbType.Binary);
myParameter.Value = fs;
cmd.Parameters.Add(myParameter);
try
{
connection.Open();
int rows = cmd.ExecuteNonQuery();
return rows;
}
catch (System.Data.SqlClient.SqlException E)
{
throw new Exception(E.Message);
}
finally
{
cmd.Dispose();
connection.Close();
}
}
}
/// <summary>
/// 執行一條計算查詢結果語句,返回查詢結果(object)。
/// </summary>
/// <param name="SQLString">計算查詢結果語句</param>
/// <returns>查詢結果(object)</returns>
public static object GetSingle(string SQLString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand(SQLString, connection))
{
try
{
connection.Open();
object obj = cmd.ExecuteScalar();
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
return null;
}
else
{
return obj;
}
}
catch (System.Data.SqlClient.SqlException e)
{
connection.Close();
throw new Exception(e.Message);
}
}
}
}
/// <summary>
/// 執行查詢語句,返回SqlDataReader
/// </summary>
/// <param name="strSQL">查詢語句</param>
/// <returns>SqlDataReader</returns>
public static SqlDataReader ExecuteReader(string strSQL)
{
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(strSQL, connection);
try
{
connection.Open();
SqlDataReader myReader = cmd.ExecuteReader();
return myReader;
}
catch (System.Data.SqlClient.SqlException e)
{
throw new Exception(e.Message);
}
}
/// <summary>
/// 執行查詢語句,返回DataSet
/// </summary>
/// <param name="SQLString">查詢語句</param>
/// <returns>DataSet</returns>
public static DataSet Query(string SQLString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet ds = new DataSet();
try
{
connection.Open();
SqlDataAdapter command = new SqlDataAdapter(SQLString, connection);
command.Fill(ds, "ds");
}
catch (System.Data.SqlClient.SqlException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
/// <summary>
/// 執行查詢語句,返回datatable
/// </summary>
/// <param name="SQLString">查詢語句</param>
/// <returns>DataSet</returns>
public static DataTable QueryTable(string SQLString)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet ds = new DataSet();
try
{
connection.Open();
SqlDataAdapter command = new SqlDataAdapter(SQLString, connection);
command.Fill(ds, "ds");
}
catch (System.Data.SqlClient.SqlException ex)
{
throw new Exception(ex.Message);
}
return ds.Tables[0];
}
}
#endregion
#region 執行帶參數的SQL語句
/// <summary>
/// 執行SQL語句,返回影響的記錄數
/// </summary>
/// <param name="SQLString">SQL語句</param>
/// <returns>影響的記錄數</returns>
public static int ExecuteSql(string SQLString, params SqlParameter[] cmdParms)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
try
{
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
int rows = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return rows;
}
catch (System.Data.SqlClient.SqlException E)
{
throw new Exception(E.Message);
}
}
}
}
/// <summary>
/// 執行多條SQL語句,實現數據庫事務。
/// </summary>
/// <param name="SQLStringList">SQL語句的哈希表(key爲sql語句,value是該語句的SqlParameter[])</param>
public static void ExecuteSqlTran(Hashtable SQLStringList)
{
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlTransaction trans = conn.BeginTransaction())
{
SqlCommand cmd = new SqlCommand();
try
{
//循環
foreach (DictionaryEntry myDE in SQLStringList)
{
string cmdText = myDE.Key.ToString();
SqlParameter[] cmdParms = (SqlParameter[])myDE.Value;
PrepareCommand(cmd, conn, trans, cmdText, cmdParms);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
trans.Commit();
}
}
catch
{
trans.Rollback();
throw;
}
}
}
}
/// <summary>
/// 執行一條計算查詢結果語句,返回查詢結果(object)。
/// </summary>
/// <param name="SQLString">計算查詢結果語句</param>
/// <returns>查詢結果(object)</returns>
public static object GetSingle(string SQLString, params SqlParameter[] cmdParms)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
try
{
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
object obj = cmd.ExecuteScalar();
cmd.Parameters.Clear();
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
return null;
}
else
{
return obj;
}
}
catch (System.Data.SqlClient.SqlException e)
{
throw new Exception(e.Message);
}
}
}
}
/// <summary>
/// 執行查詢語句,返回SqlDataReader
/// </summary>
/// <param name="strSQL">查詢語句</param>
/// <returns>SqlDataReader</returns>
public static SqlDataReader ExecuteReader(string SQLString, params SqlParameter[] cmdParms)
{
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand();
try
{
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
SqlDataReader myReader = cmd.ExecuteReader();
cmd.Parameters.Clear();
return myReader;
}
catch (System.Data.SqlClient.SqlException e)
{
throw new Exception(e.Message);
}
}
/// <summary>
/// 執行查詢語句,返回DataSet
/// </summary>
/// <param name="SQLString">查詢語句</param>
/// <returns>DataSet</returns>
public static DataSet Query(string SQLString, params SqlParameter[] cmdParms)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
try
{
da.Fill(ds, "ds");
cmd.Parameters.Clear();
}
catch (System.Data.SqlClient.SqlException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
}
public static DataTable QueryTable(string SQLString, params SqlParameter[] cmdParms)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand();
PrepareCommand(cmd, connection, null, SQLString, cmdParms);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
try
{
da.Fill(ds, "ds");
cmd.Parameters.Clear();
}
catch (System.Data.SqlClient.SqlException ex)
{
throw new Exception(ex.Message);
}
return ds.Tables[0];
}
}
}
private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, string cmdText, SqlParameter[] cmdParms)
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
if (trans != null)
cmd.Transaction = trans;
cmd.CommandType = CommandType.Text;//cmdType;
if (cmdParms != null)
{
foreach (SqlParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
}
#endregion
#region 存儲過程操作
/// <summary>
/// 執行存儲過程
/// </summary>
/// <param name="storedProcName">存儲過程名</param>
/// <param name="parameters">存儲過程參數</param>
/// <returns>SqlDataReader</returns>
public static SqlDataReader RunProcedure(string storedProcName, IDataParameter[] parameters)
{
SqlConnection connection = new SqlConnection(connectionString);
SqlDataReader returnReader;
connection.Open();
SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters);
command.CommandType = CommandType.StoredProcedure;
returnReader = command.ExecuteReader();
return returnReader;
}
/// <summary>
/// 執行存儲過程
/// </summary>
/// <param name="storedProcName">存儲過程名</param>
/// <param name="parameters">存儲過程參數</param>
/// <param name="tableName">DataSet結果中的表名</param>
/// <returns>DataSet</returns>
public static DataSet RunProcedure(string storedProcName, IDataParameter[] parameters, string tableName)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
DataSet dataSet = new DataSet();
connection.Open();
SqlDataAdapter sqlDA = new SqlDataAdapter();
sqlDA.SelectCommand = BuildQueryCommand(connection, storedProcName, parameters);
sqlDA.Fill(dataSet, tableName);
connection.Close();
return dataSet;
}
}
/// <summary>
/// 構建 SqlCommand 對象(用來返回一個結果集,而不是一個整數值)
/// </summary>
/// <param name="connection">數據庫連接</param>
/// <param name="storedProcName">存儲過程名</param>
/// <param name="parameters">存儲過程參數</param>
/// <returns>SqlCommand</returns>
private static SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
{
SqlCommand command = new SqlCommand(storedProcName, connection);
command.CommandType = CommandType.StoredProcedure;
foreach (SqlParameter parameter in parameters)
{
command.Parameters.Add(parameter);
}
return command;
}
/// <summary>
/// 執行存儲過程,返回影響的行數
/// </summary>
/// <param name="storedProcName">存儲過程名</param>
/// <param name="parameters">存儲過程參數</param>
/// <param name="rowsAffected">影響的行數</param>
/// <returns></returns>
public static int RunProcedure(string storedProcName, IDataParameter[] parameters, out int rowsAffected)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
int result;
connection.Open();
SqlCommand command = BuildIntCommand(connection, storedProcName, parameters);
rowsAffected = command.ExecuteNonQuery();
result = (int)command.Parameters["ReturnValue"].Value;
//Connection.Close();
return result;
}
}
/// <summary>
/// 創建 SqlCommand 對象實例(用來返回一個整數值)
/// </summary>
/// <param name="storedProcName">存儲過程名</param>
/// <param name="parameters">存儲過程參數</param>
/// <returns>SqlCommand 對象實例</returns>
private static SqlCommand BuildIntCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
{
SqlCommand command = BuildQueryCommand(connection, storedProcName, parameters);
command.Parameters.Add(new SqlParameter("ReturnValue",
SqlDbType.Int, 4, ParameterDirection.ReturnValue,
false, 0, 0, string.Empty, DataRowVersion.Default, null));
return command;
}
#endregion
}
}