日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET3.5 企业级项目开发 -- 第二章(续) 数据访问层(DAL)的开发解决方案提出...

發布時間:2025/3/17 asp.net 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET3.5 企业级项目开发 -- 第二章(续) 数据访问层(DAL)的开发解决方案提出... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??????????????????ASP.NET3.5 企業級項目開發 -- 第二章(續) 數據訪問層(DAL)的開發解決方案提出

???????前言:首先給大家說聲"對不起",因為自從打算寫這系列的文章以來,得到大家很多的支持,謝謝大家!最近因為公司的事和朋友找工作的事,沒有怎么接著寫了,也調了大家的胃口,還希望園子里的朋友原諒!

???????本篇主要是講述數據層的開發,之前的一篇文章已經給出了很多的選中的方案,如SqlHelper,DataTable/DataSet,以及自定義實體。但是我們說過了,那些方案都有不盡人意的地方,所以我們就提出用Linq,找個方案就比之前好一些,但是也不是那么完美了。
?
???????本篇的話題如下:
???????Linq中自定義方法
???????提出解決方案

???????Linq中自定義方法

???????在此之前,我們先要講清楚一個問題:在Linq中的自定義存儲過程。
???????我們知道,當我們把數據庫中的一張表拖放到Linq的ORM設計器上以后,ORM就自動生成了很多的方法,如Delete,Update,Insert方法,這些方法都是自動生成的,一般是沒有什么問題的,但是一個項目的開發中,很多時候我們都要把這些方法進行定制。那么我們就要用自己的存儲過程。

???????一般情況下,我們可以在我們的數據庫中定義一些的存儲過程,如下,我們在之前定義的ENTUserAccount表中添加一條數據:
?

Code
CREATE?PROCEDURE?ENTUserAccountInsert
?(
??
@WindowsAccountName?varchar(50),
??
@FirstName?varchar(50),
??
@LastName?varchar(50),
??
@Email?varchar(100),
??
@IsActive?bit,
??
@InsertENTUserAccountId?int
?)
?
AS
?
SET?NOCOUNT?ON
?
INSERT?INTO?ENTUserAccount(WindowsAccountName,?FirstName,?LastName,
??Email,?IsActive,?InsertENTUserAccountId,?InsertDate,
???UpdateENTUserAccountId,?UpdateDate)
?
VALUES?(@WindowsAccountName,?@FirstName,?@LastName,?@Email,
?
@IsActive,?@InsertENTUserAccountId,?GetDate(),
??
@InsertENTUserAccountId,?GetDate())
?
RETURN

?
???????我們接來進行下面的操作;
???????1.把這個存儲過程拖放到ORM設計器的右邊的方法面板中,這樣存儲過程就自動的生成一個方法。
???????2.在ORM中點擊ENTUserAccount表,選擇屬性中的Insert,如圖:(插圖出現問題,大家原諒!!!)
?
???????3.在出現的面板中,我們選擇Customer(自定義)。選擇我們之前由存儲過程實生成的的方法,確認就OK了。

???????如果我們在我們的以后的代碼中調用HRPaidTimeOffDataContext.InsertENTUseAccount方法,那么此時我們就實際上調用我們自定義的方法了,之前自動生成的Insert方法就不調用了。
?
???????同理,Update,Delete方法的自定義也是一樣的。
?
???????提出解決方案

???????約定:我們以后的存儲過程的命名采用方式:表名+操作,如ENTUserAccountInsert。

???????首先我們創建一下存儲過程:

???????ENTUserAccount表中插入數據


?

Code
CREATE?PROCEDURE?[dbo].[ENTUserAccountInsert]
?(
??
@ENTUserAccountId?int?OUTPUT,
??
@WindowsAccountName?varchar(50),
??
@FirstName?varchar(50),
??
@LastName?varchar(50),
??
@Email?varchar(100),
??
@IsActive?bit,
??
@InsertENTUserAccountId?int
?)
?
AS
?
SET?NOCOUNT?ON
??
INSERT?INTO?ENTUserAccount?(WindowsAccountName,?FirstName,
???LastName,?Email,?IsActive,?InsertDate,
???InsertENTUserAccountId,?UpdateDate,
???UpdateENTUserAccountId)
??
VALUES?(@WindowsAccountName,?@FirstName,?@LastName,
???
@Email,?@IsActive,?GetDate(),
???
@InsertENTUserAccountId,?GetDate(),
???
@InsertENTUserAccountId)

??
SET?@ENTUserAccountId?=?Scope_Identity()
??
RETURN

?

?

???????ENTUserAccount表中更新數據

?

?

Code
CREATE?PROCEDURE?[dbo].[ENTUserAccountUpdate]
?(
??
@ENTUserAccountId?int,
??
@WindowsAccountName?varchar(50),
??
@FirstName?varchar(50),
??
@LastName?varchar(50),
??
@Email?varchar(100),
??
@IsActive?bit,
??
@UpdateENTUserAccountId?int,
??
@Version?timestamp
?)
?
AS
?
SET?NOCOUNT?ON
?
UPDATE?ENTUserAccount
?
SET?WindowsAccountName?=?@WindowsAccountName
??,?FirstName?
=?@FirstName
??,?LastName?
=?@LastName
??,?Email?
=?@Email
??,?IsActive?
=?@IsActive
??,?UpdateDate?
=?GetDate()
??,?UpdateENTUserAccountId?
=?@UpdateENTUserAccountId
?
WHERE?ENTUserAccountId?=?@ENTUserAccountId
?
AND?Version?=?@Version
?
RETURN?@@ROWCOUNT

?ENTUserAccount表中刪除數據
?
?
CREATE?PROCEDURE?[dbo].[ENTUserAccountDelete]
?(
??
@ENTUserAccountId?int
?)
?
AS
?
SET?NOCOUNT?ON
?
DELETE?FROM?ENTUserAccount
??
WHERE?ENTUserAccountId?=?@ENTUserAccountId
?
RETURN

?

?

????????獲取ENTUserAccount表中所有記錄

?


Code
?CREATE?PROCEDURE?ENTUserAccountSelectAll
?
AS
?
SET?NOCOUNT?ON
?
SELECT?ENTUserAccountId,?WindowsAccountName,?FirstName,?LastName,
??Email,?IsActive,?InsertDate,?InsertENTUserAccountid,
??UpdateDate,?UpdateENTUserAccountId,?Version
?
FROM?ENTUserAccount
?
RETURN

?

???????通過ENTUserAccountId來查找記錄
?
?

Code
CREATE?PROCEDURE?ENTUserAccountSelectById
?(
??
@ENTUserAccountId?int
?)
?
AS
?
SET?NOCOUNT?ON
?
SELECT?ENTUserAccountId,?WindowsAccountName,?FirstName,?LastName,
??Email,?IsActive,?InsertDate,?InsertENTUserAccountid,
??UpdateDate,?UpdateENTUserAccountId,?Version
??
FROM?ENTUserAccount
??
WHERE?ENTUserAccountId?=?@ENTUserAccountId
?
RETURN

?

??????? 以前的存儲過程沒有和大家以前做的項目一樣,是很普通的一些存儲過程。
???????寫完上面的存儲過程之后,大家把Insert,Update,Delete的存儲過程拖到ORM的方法面板中生成方法,然后按照我們之前說的方法定制,把ENTUserAccount的Update,Insert等方法都配置成為我們自己寫的方法。


???????注意:對于Select的存儲過程,我們不應該把它們直接拖到方法面板中,我們而是把ENTUserAccountSelectAll,ENTUserAccountSelectById存儲過程拖到到ORM設計器中的ENTUserAccount表上。因為只有這樣,自定生成的代碼才返回ENTUserAccount類的類型;如果是像之前那樣拖到方法面板中,那么返回值就是ISingle<ENTUserAccount>,大家之后會看到原因的。
?
???????之前,我們就在V2.PaidTimeOffDAL中創建一個文件夾,命名為Framework。讓后在這個文件夾下面添加一個類,命名為IENTBaseEntity.cs

?

Code
?namespace?V2.PaidTimeOffDAL.Framework
?{
??
public?interface?IENTBaseEntity
??{
???DateTime?InsertDate?{?
get;?set;?}
???
int?InsertENTUserAccountId?{?get;?set;?}
???DateTime?UpdateDate?{?
get;?set;?}
???
int?UpdateENTUserAccountId?{?get;?set;?}
???Binary?Version?{?
get;?set;?}
??}
?}

?

???????因為Binary 類型是在System.Data.Linq下的,所以我們在類中添加這個命名空間的引用。
?
???????大家在想:為什么我們要定義這么一個接口?
?
???????原因有兩點:
???????1.因為我們的這個項目中之后會有審計跟蹤的功能,就是說數據庫中記錄的每次修改都會記錄下是誰在什么時候修改的,而且我們的所有的表中都會有上面的5個字段。定義接口這樣做為了使得每個類都必需定義必需有上面的5個字段。


???????2.定義接口,可以實現一些依賴倒置的原則,以后大家會看到效果的。

?
???????添加完上面的類之后,那么我們就再添加一個類:CustomizedEntities.cs ,這個類不在Framework文件夾中,而是直接加在外面的。

?

?using?V2.PaidTimeOffDAL.Framework;
?
namespace?V2.PaidTimeOffDAL
?{
??
public?partial?class?ENTUserAccount?:?IENTBaseEntity?{?}
?}

?

???????大家可能會想:ENTUserAccount類是個partial類,那么就說明這個類之前已經在什么地方有了的?
???????不錯!我們之前說要把ENTUserAccountById的存儲過程拖到ENTUserAccount表上,其實我們就是想生成這個和數據表同名的ENTUserAccount類。
?我們使得這個類實現這個接口,那么我們以后就可以"針對接口編程"。


???????其實我們知道我們的DAL數據層的功能很明了:和數據庫直接打交道,實現增,刪,改,查操作。
?
???????為了使得我們所有的數據操作統一,我們定義了一個基類,以后的所有數據庫操作類都實現它。
???????我們在Framework文件夾中添加類:ENTBaseData.cs
?
?

Code
public?abstract?class?ENTBaseData<T>?where?T?:?IENTBaseEntity
?{
??
public?abstract?List<T>?Select();

??
public?abstract?T?Select(int?id);

??
public?abstract?void?Delete(HRPaidTimeOffDataContext?db,?int?id);

??
public?void?Delete(string?connectionString,?int?id)
??{
???
using?(HRPaidTimeOffDataContext?db?=?new
????HRPaidTimeOffDataContext(connectionString))
???{
????Delete(db,?id);
???}
??}
?}

?


?

??????類的編寫也不難理解:就是有寫操作數據的方法。大家還要注意一點:Delete方法的實現,我們采用了Template Method設計模式,也就是常說的"鉤子方法",實現的原因,現在講述不是很好理解,沒有一種自然的過程,我以后會說的。
?
???????這樣我們就定義這樣的一個基類,然后針對每個表都有數據操作,那么我們就讓每個表的數據操作類都繼承這個基類。
???????注意:大家在上面的基類中,沒有看到Insert和Update方法,只是有原因的。如果我們在基類中寫了Insert方法,就會傳入一個T參數,如下:
?????

??public?bool?Insert(T?entUserAccount)

?
???????這樣是沒有錯,但是不是很好。如果我們的entUseAccount中如果有寫字段沒有賦值,那么我們插入就出問題。
???????所以我們的實現方法是:直接在不同的數據操作類中,針對特定的表寫Insert和Update方法。
?
???????我們就來看看ENTUserAccount數據表的操作類的實現:


?

Code
public?class?ENTUserAccountData?:?ENTBaseData<ENTUserAccount>
?????{
????????

????????
public?override?List<ENTUserAccount>?Select()
????????{
????????????
using?(HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext(DBHelper.GetHRPaidTimeOffConnectionString()))
????????????{
????????????????
return?db.ENTUserAccountSelectAll().ToList();????????????????
????????????}
????????}

????????
public?override?ENTUserAccount?Select(int?id)
????????{
????????????
using?(HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext(DBHelper.GetHRPaidTimeOffConnectionString()))
????????????{
????????????????
return?Select(db,?id);
????????????}
????????}

??

???????上面方法很簡單:直接調用自動生成的方法。
?
???????至于DBHelper.GetHRPaidTimeOffConnectionString()方法,就是把數據庫的鏈接字符串從web.config文件中讀出。
?
???????下面我們就來看看Delete方法的實現:

?

??public?override?void?Delete(HRPaidTimeOffDataContext?db,?int?id)
????????{
????????????db.ENTUserAccountDelete(id);
????????}

?

???????我們之前說過,只是一個Template Method模式的使用,使用的意圖是:把具體實現延遲到子類。可能在以后的項目中,我們的數據庫要更改了,表也改了,那時,我們的 ENTUserAccount數據表可能改為User表,那么我們之前實現的代碼不變,只要重寫Delete方法就行了,如
?

?public?override?void?Delete(HRPaidTimeOffDataContext?db,?int?id)
????????{
????????????db.?User?Delete(id);
????????}
?

?
???????下面,我們就來看看Insert方法:

???????其實實現也很簡單,我們采用和SqlHelper相同的方式:第一個方法傳入HRPaidTimeOffDataContext ,第二個方法傳入connectionString
?
???????而且我們傳入的參數是和ENTUserAccount表相對應的字段,這樣就比只是傳入一個ENTUserAccount類要好。

?

Code
public?int?Insert(string?connectionString,?string?windowsAccountName,?string?firstName,
????????????
string?lastName,?string?email,?bool?isActive,?int?insertUserAccountId)
????????{
????????????
using?(HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext(connectionString))
????????????{
????????????????
return?Insert(db,?windowsAccountName,?firstName,?lastName,?email,?isActive,?insertUserAccountId);
????????????}
????????}


????????
public?int?Insert(HRPaidTimeOffDataContext?db,?string?windowsAccountName,?string?firstName,?
????????????
string?lastName,?string?email,?bool?isActive,?int?insertUserAccountId)
????????{
????????????Nullable
<int>?entUserAccountId?=?0;

????????????db.ENTUserAccountInsert(
ref?entUserAccountId,?windowsAccountName,?firstName,?lastName,?
????????????????email,?isActive,?insertUserAccountId);

????????????
return?Convert.ToInt32(entUserAccountId);
????????}


????????同理,Update方法實現如下;
?

?

Code
?public?bool?Update(string?connectionString,?int?userAccountId,?string?windowsAccountName,
????????????
string?firstName,?string?lastName,?string?email,?bool?isActive,?int?updateUserAccountId,
????????????Binary?version)
????????{
????????????
using?(HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext(connectionString))
????????????{
????????????????
return?Update(db,?userAccountId,?windowsAccountName,?firstName,?lastName,?email,
????????????????????isActive,?updateUserAccountId,?version);
????????????}
????????}

????????
public?bool?Update(HRPaidTimeOffDataContext?db,?int?userAccountId,?string?windowsAccountName,?
????????????
string?firstName,?string?lastName,?string?email,?bool?isActive,?int?updateUserAccountId,?
????????????Binary?version)
????????{
????????????
int?rowsAffected?=?db.ENTUserAccountUpdate(userAccountId,?windowsAccountName,?firstName,?
????????????????lastName,?email,?isActive,?updateUserAccountId,?version);
????????????
return?rowsAffected?==?1;
????????}

?
???????

??????到這里,我們的DAL的實現的示例就到這里,當然,我們這里只有一個表,但是我們通過這個示例知道了我們之后實現方法,其他表的實現數據操作的方式一樣的,隨著深入的講述,大家會看到的!

?? 為了大家交流,已經創建企業項目開發團隊,希望大家也以后會把有關企業開發的文章放入團隊中,希望大家積極參加這個團隊。而且我以后也會發表更多的項目示例,大家一起學習進步!

???????注:大家留言后,我手動的添加。因為dudu說只能這樣添加,現在博客園團隊的功能很有限,只能手動添加成員!

總結

以上是生活随笔為你收集整理的ASP.NET3.5 企业级项目开发 -- 第二章(续) 数据访问层(DAL)的开发解决方案提出...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。