ASP.NET3.5 企业级项目开发 -- 第二章 数据访问层(DAL)的开发
為什么80%的碼農都做不了架構師?>>> ??
????????????????????????????????????ASP.NET3.5 企業級項目開發 -- 第二章 數據訪問層(DAL)的開發
?
???????前言:本篇主要講述數據訪問層的開發,而且為了大家交流,已經創建企業項目開發團隊,希望大家也以后會把有關企業開發的文章放入團隊中,希望大家積極參加這個團隊。而且我以后也會發表更多的項目示例,大家一起學習進步!
?
???????本篇的話題主要如下:
???????問題提出
???????設計方案
?
???????問題提出
?
???????數據訪問層(DAL)的目標創建一些以便業務層來調用的類和方法。我們之前總是用GridView來綁定DataSet和DataReader,但是在稍微大點的項目開發中DAL不能直接和用戶
??????界面打交道。
??????
???????一般來說,DAL是用來和數據庫和BLL打交道的,也就是處理BLL和數據庫的中間。數據以什么形式在DAL和BLL之前傳遞有很多的爭論。不同的人有不同的意見,數據傳遞的形式有:DataSet,強類型的DataSet,DataReader,自定義實體。在介紹Ling to Sql之后,大家心里會有清晰的答案。在以前的開發中,我們一般是采用ADO.NET來和數據庫打交道,那么就需要我們的開發人員對ADO.NET有一定的比較深入的了解,但是當我們用Linq to? Sql之后,我們可以很方便的使用DataContext來與數據庫拉打交道,而不需要我們懂得很多的ADO.NET的知識,但是在Linq to Sql的背后還是在采用ADO.NET來和數據庫交互的。
?
???????還有就是事務處理的問題。關于事務的概念,相信大家都清楚,我也不贅述了。事務處理在什么地方實現有如下意見:在存儲過程中直接用SQL語句來寫;在DAL層處理,
??????在BLL層處理。當然,每一種的選擇都有各自的理由和利弊。還有一點要注意的是:不要把事務處理的代碼到處寫,如在DAL層中寫一點,在BLL中寫一點。
?
?
?
???????設計方案
?
???????在設計方案中實際上就是提供幾個選擇來解決之前我們提出的問題。以下就是兩個選擇:
???????1.DAL只要是執行CRUD操作,CRUD是就是:Create,Read,Update,Delete.在.NET Framwework中提供了很多和數據庫打交道的ADO.NET類和方法,如
SqlConnection,SqlCommand,SqlCommand.ExecuteNonQuery()等,用過ADO.NET的朋友應該清楚這些常用的類,我這里也不羅嗦。
?
???????2.SqlHelper
?用過ADO.NET的朋友應該知道,在我們開發過程中,很多時候寫ADO.NET代碼的時候,代碼結構和功能都是大同小異的,所以基于此,微軟就開發了Microsoft Data Access Application Block,只要我們調用其中的一些方法,傳入一些參數就行了,不需要我們再去寫那些繁瑣的ADO.NET代碼,因為這個數據訪問塊都已經封裝好了。其中一個最重要的類就是SqlHelper.這個類是個靜態類,提供了很多的方法,如下:
???????ExecuteNonQuery
???????ExecuteDataset
???????ExecuteReader
???????ExecuteScalar
???????FillDataset
???????上面 方法的設計包含了很多OO的思想。我們來看看ExecuteNonQuery方法 ,其他的方法的設計思想和方式一樣的:
?
?
Code//連接字符串
?public?static?int?ExecuteNonQuery(string?connectionString,?CommandType?commandType,string?commandText)
?{?…?}
?public?static?int?ExecuteNonQuery(string?connectionString,?CommandType?commandType,string?commandText,?params?SqlParameter[]?commandParameters)
?{?…?}
?public?static?int?ExecuteNonQuery(string?connectionString,?string?spName,?params?object[]?parameterValues)
?{?…?}
?
?
?
?
Code?//連接對象
?public?static?int?ExecuteNonQuery(SqlConnection?connection,?CommandType?commandType,?string?commandText)
?{?…?}
?public?static?int?ExecuteNonQuery(SqlConnection?connection,?CommandType?commandType,?string?commandText,?params?SqlParameter[]?commandParameters)
?{?…?}
?public?static?int?ExecuteNonQuery(SqlConnection?connection,?string?spName,?params?object[]?parameterValues)
?{?…?}
?
?
?//事務對象
?public?static?int?ExecuteNonQuery(SqlTransaction?transaction,?CommandType?commandType,?string?commandText)
?{?…?}
?public?static?int?ExecuteNonQuery(SqlTransaction?transaction,?CommandType?commandType,?string?commandText,?params?SqlParameter[]?commandParameters)
?{?…?}
public?static?int?ExecuteNonQuery(SqlTransaction?transaction,?string?spName,?params?object[]?parameterValues)
?{?…?}
?
???????上面前3個方法都是采用了一個連接字符串的參數,而接下來的3個方法是采用了一個連接對象為參數,最后的3個方法采用了一個事務對象為參數。這些方法在調用存儲過程時提供了很大的靈活性。 例如:
?
?CREATE?PROCEDURE?UserAccountInsert(
??@Name?varchar(50),
??@UserAccountId?int?OUTPUT
?)
?AS
?SET?NOCOUNT?ON
??INSERT?INTO?UserAccount?(Name)?VALUES?(@Name)
?SET?@UserAccountId?=?Scope_Identity()
??
?調用代碼如下:
?
?public?int?InsertUserAccount(string?connectionString,?string?name)
?{
??SqlParameter[]?parameters?=
??{
???new?SqlParameter(?"@Name",?SqlDbType.VarChar,?50),
???new?SqlParameter(?"@UserAccountId",?SqlDbType.Int)
??};
??parameters[].Value?=?name;
??parameters[1].Direction?=?ParameterDirection.Output;
??SqlHelper.ExecuteNonQuery(connectionString,CommandType.StoredProcedure,?"UserAccountInsert",??parameters);
??return?Convert.ToInt32(parameters[1].Value);
?}
?
?
??????? 還有一個問題要注意就是更新時的同步問題。例如,用戶從數據庫中獲取一條數據,然后更改了一些內容,之后就保存記錄到數據庫中,那么系統就應該只保存用戶之前取出的那條數據。為了達到這個效果,我們可以在每次數據更新的時候添加一個datetime類型或者int類型的字段來標記。當我們從數據庫中返回一條記錄時,我們在UI顯示層顯示出來,然后修改數據,再保存到數據庫中,那么我們在數據庫中的存儲過程的SQL語句就只是更新之前我們取出的那條數據。在Sql Server 2005中,我們可以用timespan類型的字段來跟蹤和標識每條數據的版本,所以sql語句如下:
?
?CREATE?PROCEDURE?UserAccountUpdate(
??@Name?varchar(50),
??@UserAccountId?int,
??@LastUpdateDate?datetime
?)
?AS
?UPDATE?UserAccount
??SET?Name?=?@Name,
??LastUpdateDate?=?GetDate()
??WHERE?UserAccountId?=?@UserAccountId
??AND?LastUpdateDate?=?@LastUpdateDate
?
???????請大家注意LastUpdateDate 字段其實就是一個標識每條數據版本的輔助字段。
???????調用的C#代碼如下:
?
?public?bool?UpdateUserAccount(string?connectionString,?string?name,?int?userAccountId,?DateTime?lastUpdateDate)
?{
??SqlParameter[]?parameters?=
??{
???new?SqlParameter(?"@Name",?SqlDbType.VarChar,?50),
???new?SqlParameter(?"@UserAccountId",?SqlDbType.Int),
???new?SqlParameter(?"@LastUpdateDate",?SqlDbType.DateTime)
??};
??parameters[].Value?=?name;
??parameters[1].Value?=?userAccountId;
??parameters[2].Value?=?lastUpdateDate;
??int?rowsAffected?=
??Convert.ToInt32(SqlHelper.ExecuteNonQuery(connectionString,
??CommandType.StoredProcedure,?"UserAccountUpdate",?parameters));
??return?rowsAffected?==?1;
?}?
?
?
???????下面我們就來看看數據在DAL和BLL之間是以什么形式來交換的,一般有以下選擇:
?
???????DataSet
???????類型化的DataSet
???????自定義實體
?
?
???????當BLL類調用從DAL中的一些方法拉獲取數據時,它們將怎樣接受這些數據?
???????是用DataSet/DataTable,還是自定義實體?
???????下面我們就看看給自的優缺點:
?
???????如果選擇使用DataSet/DataTable在DAL和BLL層之前傳遞數據,就需要使用ADO.NET中的方法來訪問BLL中的數據。如果選擇自定義實體,那么所有的數據將被封裝到自定義實體類和類的集合中,這樣就可以根據具體情況來訪問BLL,這中方式更加的自然。
?
???????很多人認為DataSet/DataTable對于基于桌面的只能客戶端程序來說是最好的選擇,但是對于可擴展的高性能Web網站來說,則不夠強大。這里所說的DataSet是指類型化的DataSet,因為非類型化的DataSet有很多的確定:進行配置和編碼時,很容易把表名,字段名,關系名,或者字段的類型搞錯,而且在調試的時候花費很多的時間。而類型化的DataSet很容易使用,因為它可以使用智能感應來獲得字段名,而且還內置了排序和過濾的功能,執行數據綁定而且DataSet/DataTable還是可以序列化的,這樣就可以更加容易的傳輸它們。
???????DataSet/DataTable的缺點:性能和擴展性的局限性,數據的表示形式和業務規則驗證。如果只需要傳遞一條數據,那么我們仍然需要創建一個完整的DataSet/DataTable,這就需要系統開銷。而且DataSet/DataTable和數據庫的關于很密切,可以說是內存中的數據庫,所以DataSet/DataTable沒有一個清晰的,面向對象的數據表示方式。盡管DataSet/DataTable同IDE集成的很好,但是每次數據庫結構發生變化,如添加字段,重命名等,那么我們就得重新創建類型化的DataSet.最大的問題就是:在DataSet中添加自定義的業務和驗證邏輯困難。在將它們保存到數據庫之前,或者在運行其他語句之前要對那些新記錄強制之心業務規則,需要寫很多的代碼,而且需要深入的了解ADO.NET的知識。大家要明白?如果使用的是自定義的實體,那么我們就需要手動的把數據庫中的表映射為自定義的業務類,而且這將是一項麻煩的事情,而且還有一點很之前的DataSet/DataTable一樣:如果數據庫中的表結構變化,那么我們又得重新修改我們的自定義的業務類,
?
???????我們真的就沒有辦法了嗎?
???????有,絕對有方法可以解決上面的問題,那么就Linq to Sql 和它的ORM設計器。
?
??
???????下面我們就看看Linq to Sql
?
???????注:在本章中,不需要大家對Linq很熟悉,只要了解就行了,因為對與用到的知識,會詳細的講述的。而且大家一定要一步步的跟著做,切記!
???????在VS2008中,一個改進的功能就是Linq還有就是對象關系模型(ORM)設計器,ORM設計器可以自動的生成類,并且自動進行ADO.NET的操作。其中一個最中要的類就是DataContext,大家可以把這個類和我們之前談的SqlHelper類來類比,它們都是封裝了數據操作的細節。
?
?
???????下面請大家跟著我一起來做:
???????1.創建一個新的Sql Server 2005 數據庫,或者直接用VS2008自帶的SQL Exss創建也行,如下:
?
?
?
??????
???????2.數據庫名稱為HRPaidTimeOff
???????3.創建ENTUserAccount表,如下:
???????我們在這個項目中的所有表都以ENT為前綴,表明這個表是可重用企業級框架的一部分。還有ENTUserAccountId是identity的。
???????來看看表的定義和字段的意義:這個表其實就是一個用戶賬戶表,其中ENTUserAccountId就是用戶賬戶的ID,也是主鍵,WindowsAccountName就是用戶的計算機名稱,FirstName,LastName就是用戶名字,Email用戶郵箱,IsActive表明這個用戶是否是激活狀態,后面的IsertDate,InsertENTUserAccountId,UpdateDate,UpdateENTUserAccountId,
??????這幾個字段在我們項目的所有的表中都有的,因為我們之后要添加審計和跟蹤功能要用到這些字段,它們的意義分別是:用戶添加的時間,是哪個用戶添加了當前的這個用戶,用戶更新時間,是哪個用戶更新的當前用戶。舉個例子就是:加入Mary是管理員,她添加了一個Bob用戶,那么ENTUserAccountId就是Bob用戶記錄的主鍵,FirstName就是Bob,InsertENTUserAccountId就是Mary的ID。
?
???????下面我們就添加一條記錄:
???????WindowsAccountName = Lufy
???????FirstName = Yang
???????LastName = Wang
???????Email = yangyang4502@yahoo.com.cn
???????IsActive = True
???????InsertDate=getdate()
???????InsertENTUserAccountId = 1
???????UpdateDate = getdate()
???????UpdateENTUserAccountId = 1
?
???????現在數據表就創建好了,打開VS2008創建連接(如果我們之前是直接用VS2008的服務器資源管理創建的,那么下面的步驟就不用作了,如果使用的 sql 2005,下面的步驟就要做
???????1.在VS2008中選擇"視圖"-"服務器資源管理"
???????2.點擊"數據庫連接",右擊,"添加連接",數據庫選擇"Microsoft SQL Server (SqlClient)",服務器為".\sqlexss".
???????3.選擇身份驗證方式為"Windows驗證",選擇數據庫為"HRPaidTimeOff"
???????4.測試連接,然后OK
?
???????下面我們就來創建DataContext
???????我們之前說過:DataContext和我們之前談的SqlHelper類來類比,它們都是封裝了數據操作的細節。我們在V2.PaidTimeOffDAL項目上右擊,選擇"添加新項",如下:
?
???????VS2008自動的添加System.Data.Linq的引用,同時也添加了三個文件:HRPaidTimeOff.dbml, RPaidTimeOff.dbml.layout和HRPaidTimeOff.designer.cs.其中HRPaidTimeOff.dbml, RPaidTimeOff.dbml.layout將會被ORM圖形設計器所使用,.cs文件包含了所有自動創建的類。
?
?
???????大家可以雙擊"HRPaidTimeOff.designer.cs"文件,我們就會看見VS2008創建的分部類HRPaidTimeOffDataContext,這個類繼承自System.Data.Linq.DataContext。我們可以用這個類來和數據打交道,就想我們之前使用SqlHelper類一樣。這個類有一個名為MappingSource的變量,和一些構造函數。其中構造函數有的采用一個連接字符串為參數,有的用一個實現了IDBConnection接口的類為參數,然后所有的構造函數都調用了OnCreated方法。
???????打開折疊區域--"Extensibility Method Definitions",就可以看到下面的方法:
?
?
????????這是VS2008的一個新的語法:分部方法,大家可以和之前的partial class類比。這個方法允許你在類中先定義方法,然后在該類的其他partial類中實現方法體。如果我們的partial 方法沒有實現,那么及時你調用了這個方法,也不會出錯,因為編譯器會忽略這個方法的調用。
?
???????下面,我們雙擊"HRPaidTimeOff.dbml",就可以看到圖形化的ORM設計器。然后,我們展開"服務器資源管理器"窗口,然后把PaidTimeOff數據庫總的ENTUserAccount拖到設計器的左邊。如下:
?
?
??????此時,VS2008就直接創建一個實體類來映射ENTUserAccount表,再次打開"HRPaidTimeOff.designer.cs"文件,我們可以看到這個文件和我們之前看到的就不同了,我們首先可以看到下面的Attribute被添加了:
???
?
???????而且在"Extensibility Method Definitions:"很多新的方法也添加了:
?
? partial ? void ?InsertENTUserAccount(ENTUserAccount?instance);? partial ? void ?UpdateENTUserAccount(ENTUserAccount?instance);
? partial ? void ?DeleteENTUserAccount(ENTUserAccount?instance);
?
???????而且,一個新的構造函數也添加了,這個函數采用一個連接字符串為參數和一個映射源為參數:
?{
??OnCreated();
?}
?
?
???????除此之外,還有一些類添加了,在解決方案窗口,我們可以看到Settings.settings文件和Settings.Designer.cs文件,打開Settings.Designer.cs文件,我們可以看到這個類是繼承自global::System.Configuration.ApplicationSettingsBase,有一個屬性很重要,就是HRPaidTimeOffConnectionString,這屬性返回數據庫連接字符串 ,所以在默認情況下,我們之前建立的HRPaidTimeOffDataContext的數據庫連接字符串在Settings文件中指定。
?
???????我們再回到HRPaidTimeOffDataContext類,我們可以找到一個ENTUserAccount的類,它就是數據庫表的一個映射類。
???????我們只要了解這么多就行了,下面就通過例子的使用來了解其他的知識。
?
???????添加數據記錄
???????編譯V2.PaidTimeOffDAL,我們在我們解決方案的那個網站項目這引用V2.PaidTimeOffDAL.dll,我們這里只是臨時的使用以下V2.PaidTimeOffDAL.dll而以,大家知道UI層不能直接和DAL打交道的,我們這里暫時的使用,使得大家對Linq更加的熟悉一點。
???????大家跟著做:
???????1.在網站項目中添加System.Data.Linq引用。
???????2.在Default.aspx頁面添加一個按鈕,ID為btnInsert,Text為Insert
???????3.在Default.aspx.cs添加V2.PaidTimeOffDAL引用。
???????4.在Insert按鈕點擊事件下,添加下面代碼:
?
?
protected?void?btnInsert_Click(object?sender,?EventArgs?e)
?{
??//創建DataContext實例
??HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext();
??//創建新的ENTUserAccount?對象,并且設計屬性
??ENTUserAccount?userAccount?=?new?ENTUserAccount
??{
???WindowsAccountName?=?@"VARALLO1\VaralloMadison",
???FirstName?=?"Madison",
???LastName?=?"Varallo",
???Email?=?"madison.varallo@v2.com",
???IsActive?=?true,
???InsertDate?=?DateTime.Now,
???InsertENTUserAccountId?=?1,
???UpdateDate?=?DateTime.Now,
???UpdateENTUserAccountId?=?1
??};
??//傳入數據
??db.ENTUserAccounts.InsertOnSubmit(userAccount);
??//保存到數據庫
??db.SubmitChanges();
?}
??????
???????上面的代碼其實和我們之前使用ADO.NET的形式很接近。首先我們創建一個連接實例HRPaidTimeOffDataContext和數據庫連接,然后就是創建一條數據,然后調用InsertOnSubmit方法插入數據,最后就保存數據,db.SubmitChanges()把數據保存到數據庫中。
?
???????更新數據
?
???????在Default.aspx頁面中再添加一個按鈕,ID為btnUpdate,Text為Update,按鈕事件代碼如下:
?
?
Code?protected?void?btnUpdate_Click(object?sender,?EventArgs?e)
?{
??HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext();
??ENTUserAccount?userAccount?=?db.ENTUserAccounts.Single(u?=>
???u.WindowsAccountName?==?@"VARALLO1\VaralloMadison");
??userAccount.IsActive?=?false;
??db.SubmitChanges();
?}
?
??????
???????這個段代碼和之前的差不多,首先還是實例化一個數據庫連接的對象HRPaidTimeOffDataContext ,然后用Lamdal表達式選出一條數據,然后更改IsActive =false;最后保存回數據庫中。
?
???????大家可以看到,使用Linq以后,我們再也沒有用ADO.NET的語句了,而且我們寫代碼的方式也完全改變。
?
?
???????我們從更新數據的例子中看到,我們首先從數據庫中獲取一條數據,然后改變數據,最后再次保存回數據庫。對于Web程序來說用,我們通常從數據庫中獲取一條數據,顯示在界面上,然后用戶更改數據,然后點擊按鈕回傳到服務器,那么數據就傳到了我們的DAL,DAL取執行更新操作。例如,我們把一個用戶的信息全部取出了,包含FirstName,LastName,Email,IsActive等等,那么我們的界面上面就顯示出來這些數據,我們假設是用TextBox來顯示的,那么當我們更改了其中一個數據,如IsActive,那么我們就點擊按鈕,我們此時其實就要把界面上面的所有信息,包括FirstName,LastName,WindowAccountName,Email等全部返回到服務器(大家想想我們的一般更新的存儲過程是怎樣寫的,就明白了),因為如果我們只是返回一個IsActive,服務器端根本不知道更新那條數據,此時我們在服務器端就應該寫下面的代碼:
?
??
?protected?void?btnUpdate_Click(object?sender,?EventArgs?e)
?{
??//Create?an?ENTUserAccount?object?and?set?the?properties
??ENTUserAccount?userAccount?=?new?ENTUserAccount
??{
???ENTUserAccountId?=?2,
???WindowsAccountName?=?@"VARALLO1\VaralloMadison",
???FirstName?=?"Madison",
???LastName?=?"Varallo",
???Email?=?"madison.varallo@v2.com",
???IsActive?=?false,
???UpdateDate?=?DateTime.Now,
???UpdateENTUserAccountId?=?1
??};
??HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext();
??db.ENTUserAccounts.Attach(userAccount,?true);
??db.SubmitChanges();
?}
?
???????這段代碼和之前一樣,也是把IsActive設置為false,但是我們調用的是Attach方法,而且把第二個參數設置為true,說明我們要采用更新操作。
?如果運行代碼,會報錯的:
???????An entity can only be attached as modified without original state if it declares a version member or does not have an update check policy.
?
???????意思是說,我們回傳的那條記錄在數據庫中不存在。
???????這里還有一個問題要說明:我們確實是從數據庫中獲取一條數據,然后顯示在界面上,我們更新數據后,數據要取數據庫中更新,那么數據庫怎么知道現在我們傳來的數據就是之前從數據庫中取出的那條呢?
???????所以我們就需要一個標識或者說是時間戳,來表明我們現在回傳的數據確實屬于數據庫,那么我們就修改我們的數據表ENTUserAccount,添加一個新的字段Version,類型為timespan。所以當我們取數據的時候,我們就把數據的版本Version字段保存在ViewState中,然后更新數據之后,我們把這個字段一起返回,數據庫就檢查我們傳回的Version字段是否和我們要更新的數據記錄的Version是否相同,如果相同就更新數據,如下代碼:
??????
?Page_Load事件中把Version保存:
?protected?void?Page_Load(object?sender,?EventArgs?e)
?{
??HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext();
??ENTUserAccount?userAccount?=?db.ENTUserAccounts.Single(ua?=>
??ua.WindowsAccountName?==?@"VARALLO1\VaralloMadison");
??ViewState["ENTUserAccountId"]?=?userAccount.ENTUserAccountId;
??ViewState["InsertENTUserAccountId"]?=userAccount.InsertENTUserAccountId;
??ViewState["InsertDate"]?=?userAccount.InsertDate;
??ViewState["Version"]?=?userAccount.Version;
?}
??????
???????在btnUpdate按鈕事件中,如下:
?
protected?void?btnUpdate_Click(object?sender,?EventArgs?e)
?{
??//Create?an?ENTUserAccount?object?and?set?the?properties
??ENTUserAccount?userAccount?=?new?ENTUserAccount
??{
???WindowsAccountName?=?@"VARALLO1\VaralloMadison",
???FirstName?=?"Madison",
???LastName?=?"Varallo",
???Email?=?"madison.varallo@v2.com",
???IsActive?=?false,
???UpdateDate?=?DateTime.Now,
???UpdateENTUserAccountId?=?1
??};
??userAccount.ENTUserAccountId?=Convert.ToInt32(ViewState["ENTUserAccountId"]);
??userAccount.InsertENTUserAccountId?=
??Convert.ToInt32(ViewState["InsertENTUserAccountId"]);
??userAccount.InsertDate?=Convert.ToDateTime(ViewState["InsertDate"]);
??userAccount.Version?=?(Binary)ViewState["Version"];
??HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext();
??db.ENTUserAccounts.Attach(userAccount,?true);
??db.SubmitChanges();
?}
?
????????這樣就OK了。如果大家有什么問題,就留言!
???????刪除記錄:
?
protected?void?btnDelete_Click(object?sender,?EventArgs?e)
?{
??HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext();
??//Create?an?ENTUserAccount?object
??ENTUserAccount?userAccount?=?new?ENTUserAccount();
??userAccount.ENTUserAccountId?=
??Convert.ToInt32(ViewState["ENTUserAccountId"]);
??userAccount.Version?=?(Binary)ViewState["Version"];
??db.ENTUserAccounts.Attach(userAccount);
??db.ENTUserAccounts.DeleteOnSubmit(userAccount);
??db.SubmitChanges();
?}
????????方法DeleteOnSubmit是自動生成的。我們也可以定制。我們后面談。
???????查詢數據:
???????我們可以根據條件查詢,然后綁定:
?
?protected?void?btnSelect_Click(object?sender,?EventArgs?e)
?{
??HRPaidTimeOffDataContext?db?=?new?HRPaidTimeOffDataContext();
??var?userAccounts?=
??from?u?in?db.ENTUserAccounts
??select?u;
??GridView1.DataSource?=?userAccounts;
??GridView1.DataBind();
?}
?
?
?
??????今天我們就說到這里,談了一些方法和預備的方案,我們下篇就說說在我們這個項目DAL到底如何設計。
???????為了大家交流,已經創建企業項目開發團隊,希望大家也以后會把有關企業開發的文章放入團隊中,希望大家積極參加這個團隊。而且我以后也會發表更多的項目示例,大家一起學習進步!
?
原文鏈接: http://www.cnblogs.com/yanyangtian/archive/2009/05/31/1493014.html
轉載于:https://my.oschina.net/dtec/blog/43579
總結
以上是生活随笔為你收集整理的ASP.NET3.5 企业级项目开发 -- 第二章 数据访问层(DAL)的开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【STC15库函数上手笔记】2、GPIO
- 下一篇: 【pdf】Head First 设计模式