作為一名全棧設(shè)計(jì)師伦糯,每天要面臨的挑戰(zhàn)真不少盅抚。在這個(gè)項(xiàng)目里面壮虫,我必須為windows服務(wù)器做一個(gè)定時(shí)批量修改MSSQL數(shù)據(jù)庫(kù)里面的數(shù)據(jù)的應(yīng)用践盼,那么勢(shì)必在VS 2015中新建一個(gè)Windows Forms項(xiàng)目,匯編成EXE在服務(wù)器中運(yùn)行篙骡。
那么稽坤,下面的例子就是通過(guò)VS 2015丈甸,使用Entity Framework做數(shù)據(jù)綁定的一個(gè)實(shí)例。
新建項(xiàng)目
在VS 2015中新建一個(gè)項(xiàng)目尿褪,左窗格中選擇Windows睦擂,右窗格中選擇Windows 窗體應(yīng)用程序,取名為:WinFormswithEF
安裝Entity Framework NuGet軟件包
在解決方案資源管理器中杖玲,右鍵單擊WinFormswithEF項(xiàng)目顿仇,選擇管理NuGet軟件包...
在“管理NuGet軟件包”對(duì)話框中,選擇“EntityFramework”軟件包摆马。單擊安裝臼闻。
連接數(shù)據(jù)庫(kù)
點(diǎn)擊視圖菜單,找到服務(wù)器資源管理器囤采,右鍵單擊數(shù)據(jù)連接述呐,添加連接:
可以點(diǎn)擊左下方的測(cè)試連接對(duì)數(shù)據(jù)庫(kù)進(jìn)行測(cè)試,如果顯示連接成功就表示成功了斑唬。
逆向工程師模型
我們將使用Entity Framework Designer作為Visual Studio的一部分來(lái)創(chuàng)建我們的模型市埋。
點(diǎn)擊項(xiàng)目菜單 - >添加新項(xiàng)黎泣,選擇ADO.NET 實(shí)體數(shù)據(jù)模型恕刘,取名為ProductModel
選擇下一步:
選擇從來(lái)自數(shù)據(jù)庫(kù)的EF設(shè)計(jì)器,然后單擊下一步
選擇數(shù)據(jù)連接抒倚。
選擇完畢之后褐着,點(diǎn)擊完成就可以了。
逆向工程一旦完成托呕,新模型將被添加到您的項(xiàng)目中含蓉,并打開(kāi)供您在實(shí)體框架設(shè)計(jì)器中查看。 App.config文件也已添加到您的項(xiàng)目與數(shù)據(jù)庫(kù)的連接詳細(xì)信息项郊。
EF使用模板從您的模型生成代碼馅扣,我們可以從代碼中看到數(shù)據(jù)實(shí)體類TblProductList.cs
using System;
using System.Collections.Generic;
public partial class TblProductList
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public Nullable<decimal> price { get; set; }
}
我們還可以看到,數(shù)據(jù)上下文類是被放在ProductModel.edmx里面的着降。
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class webapi2Entities : DbContext
{
public webapi2Entities()
: base("name=webapi2Entities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<TblProductList> TblProductList { get; set; }
}
因?yàn)槲疫@個(gè)程序是需要批量修改的差油,在EF使用LINQ做UPDATE大家都會(huì)知道很難實(shí)現(xiàn),那么只能再安裝NuGet軟件包:
Install-Package EntityFramework.Extended
完成代碼
打開(kāi)Form1設(shè)計(jì)窗口任洞,將工具箱的Label1,timer1移到窗口里面蓄喇,在后臺(tái)進(jìn)行代碼編寫,如下
using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using EntityFramework.Extensions;
namespace WinFormswithEF
{
public partial class Form1 : Form
{
private int counter;
public Form1()
{
InitializeComponent();
counter = 0;
timer1.Interval = 6000;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
var db = new webapi2Entities();
if (counter >= 10)
{
// Exit loop code.
timer1.Enabled = false;
counter = 0;
}
else
{
db.TblProductList.Where(s => s.Name == "dddsa").Update(s => new TblProductList()
{
Category = "oaa"
});
counter = counter + 1;
label1.Text = "運(yùn)行次數(shù): " + counter.ToString();
}
}
}
}
運(yùn)行程序交掏,測(cè)試通過(guò)妆偏。
注意
這個(gè)例程里面,是對(duì)已經(jīng)存在的數(shù)據(jù)庫(kù)進(jìn)行逆向處理盅弛,讓VS對(duì)已經(jīng)存在的數(shù)據(jù)庫(kù)進(jìn)行生成代碼钱骂。因?yàn)槲业木W(wǎng)站已經(jīng)存在叔锐,我的數(shù)據(jù)庫(kù)已經(jīng)存在。我只是需要一個(gè)程序见秽,常駐在服務(wù)器后臺(tái)掌腰,使用計(jì)時(shí)器對(duì)數(shù)據(jù)庫(kù)進(jìn)行批量操作。
對(duì)桌面應(yīng)用程序來(lái)說(shuō)张吉,使用EF并不是一個(gè)多好的主意齿梁。如果使用存儲(chǔ)過(guò)程來(lái)批量處理,反而是個(gè)更有效率的工作肮蛹。
下面是操作的步驟勺择。
新建項(xiàng)目二
在VS 2015中新建一個(gè)項(xiàng)目,左窗格中選擇Windows伦忠,右窗格中選擇Windows 窗體應(yīng)用程序省核,取名為:WinFormswithSQL
打開(kāi)文件APP.CONFIG,修改一下昆码,按照數(shù)據(jù)庫(kù)的連接進(jìn)行修改:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<connectionStrings>
<add name="WinFormswithSQL.Properties.Settings.webapi2ConnectionString"
connectionString="Data Source=.;Initial Catalog=webapi2;Persist Security Info=True;User ID=sa;Password=password"
providerName="System.Data.SqlClient" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
在引用using System.Configuration;
之前气忠,點(diǎn)擊解決資源管理器,右擊引用赋咽,添加引用旧噪,將System.Configuration 引用進(jìn)來(lái)。
新建一類脓匿,取名為conn.cs:
namespace WinFormswithSQL
{
using System.Configuration;
public class Conn
{
private static string dbconnedtionString;//緩存連接字符串
private static string dbProviderName;//緩存數(shù)據(jù)提供器名稱
static Conn()
{
dbconnedtionString = ConfigurationManager.ConnectionStrings["WinFormswithSQL.Properties.Settings.webapi2ConnectionString"].ConnectionString;
dbProviderName = ConfigurationManager.ConnectionStrings["WinFormswithSQL.Properties.Settings.webapi2ConnectionString"].ProviderName;
}
public static string DbConnectionString
{
get
{
return dbconnedtionString;
}
}
/// <summary>
/// 連接程序名和屬性
/// </summary>
public static string DbProviderName
{
get
{
return dbProviderName;
}
}
}
}
然后再新建類:DataACCess.cs
using System;
using System.Data;
using System.Data.Common;
public class DataACCess
{
static DataACCess()
{
//
// TODO: 在此處添加構(gòu)造函數(shù)邏輯
//
}
public static DbCommand CreateComand()
{
string dataProviderName = Conn.DbProviderName;
string connectionString = Conn.DbConnectionString;
DbProviderFactory factory = DbProviderFactories.GetFactory(dataProviderName);
DbConnection conn = factory.CreateConnection();
conn.ConnectionString = connectionString;
DbCommand comm = conn.CreateCommand();
comm.CommandType = CommandType.StoredProcedure;
return comm;
}
public static DataTable ExcuteselectCommmand(DbCommand command)
{
DataTable table;
try
{
command.Connection.Open();
DbDataReader reader = command.ExecuteReader();
table = new DataTable();
table.Load(reader);
reader.Close();
}
finally
{
command.Connection.Close();
}
return table;
}
public static int ExecuteNonQuery(DbCommand command)
{
// 受影響行數(shù)
int affectedRows = -1;
// 執(zhí)行該命令后確保關(guān)閉數(shù)據(jù)庫(kù)
try
{
// 打開(kāi)數(shù)據(jù)庫(kù)
command.Connection.Open();
// 執(zhí)行命令并返回行數(shù)
affectedRows = command.ExecuteNonQuery();
}
catch (Exception ex)
{
// 記錄錯(cuò)誤并且拋出他們淘钟。
Utilities.LogError(ex);
throw;
}
finally
{
// 關(guān)閉數(shù)據(jù)庫(kù)
command.Connection.Close();
}
// 返回結(jié)果
return affectedRows;
}
}
現(xiàn)在基本的手腳架已經(jīng)設(shè)置完成了,我們對(duì)數(shù)據(jù)庫(kù)的表新建一個(gè)取名為edit的存儲(chǔ)過(guò)程(存儲(chǔ)過(guò)程是由一些SQL語(yǔ)句和控制語(yǔ)句組成的被封裝起來(lái)的過(guò)程,它駐留在數(shù)據(jù)庫(kù)中陪毡,可以被客戶應(yīng)用程序調(diào)用米母,也可以從另一個(gè)過(guò)程或觸發(fā)器調(diào)用。它的參數(shù)可以被傳遞和返回毡琉。與應(yīng)用程序中的函數(shù)過(guò)程類似铁瞒,存儲(chǔ)過(guò)程可以通過(guò)名字來(lái)調(diào)用,而且它們同樣有輸入?yún)?shù)和輸出參數(shù)桅滋。):
CREATE PROCEDURE [dbo].[edit]
(@Category nvarchar(20),
@Name nvarchar(20))
AS
BEGIN
UPDATE TblProductList SET Category=@Category WHERE Name=@Name
END
最后慧耍,新建一個(gè)連接的類Access.cs就可以了
using System;
using System.Data;
using System.Data.Common;
using System.Collections.Generic;
public class Access
{
static Access()
{
//
// TODO: 在此處添加構(gòu)造函數(shù)邏輯
//
}
/// <summary>
/// 直接運(yùn)行存儲(chǔ)過(guò)程文件返回DATATABLE
/// </summary>
/// <param name="commtext">存儲(chǔ)過(guò)程文件名</param>
/// <returns></returns>
public static DataTable GETdaleis(string commtext)
{
DbCommand comm = DataACCess.CreateComand();
comm.CommandText = commtext;
return DataACCess.ExcuteselectCommmand(comm);
}
/// <summary>
/// 修改類別
/// </summary>
/// <param name="CategoryID">ID</param>
/// <param name="NAME">需要修改的名稱</param>
/// <returns></returns>
public static int edit_ctegory(string Category, string Name)
{
DbCommand comm = DataACCess.CreateComand();
comm.CommandText = "edit";
DbParameter param = comm.CreateParameter();
param.ParameterName = "@Name";
param.Value = Name;
param.Size = 20;
comm.Parameters.Add(param);
param = comm.CreateParameter();
param.ParameterName = "@Category";
param.Value = Category;
param.DbType = DbType.String;
param.Size = 20;
comm.Parameters.Add(param);
int result = -1;
try
{
//執(zhí)行存儲(chǔ)過(guò)程
result = DataACCess.ExecuteNonQuery(comm);
}
catch { }
//result = 1即執(zhí)行成功
return (result);
}
}
打開(kāi)Form1設(shè)計(jì)窗口,將工具箱的Label1,timer1移到窗口里面虱歪,在后臺(tái)進(jìn)行代碼編寫蜂绎,如下
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormswithSQL
{
public partial class Form1 : Form
{
private int counter;
public Form1()
{
InitializeComponent();
counter = 0;
timer1.Interval = 6000;
timer1.Enabled = true;
}
private void timer1_Tick_1(object sender, EventArgs e)
{
if (counter >= 10)
{
// Exit loop code.
timer1.Enabled = false;
counter = 0;
}
else
{
if (Access.edit_ctegory("ccoo1", "dddsa"))
{
if (Access.edit_ctegory("ccoo1", "dddsa")) {
counter = counter + 1;
label1.Text = "運(yùn)行次數(shù): " + counter.ToString();
}
}
}
}
}
}
運(yùn)行結(jié)果:
源代碼
WinFormswithSQL 的源代碼我放到了Github上面:https://github.com/alexzeng2014/WinFormswithSQL