![04第四講ADONET實(shí)體框架_第1頁(yè)](http://file4.renrendoc.com/view/c481639b9c4e39df9dba5563561a0b0c/c481639b9c4e39df9dba5563561a0b0c1.gif)
![04第四講ADONET實(shí)體框架_第2頁(yè)](http://file4.renrendoc.com/view/c481639b9c4e39df9dba5563561a0b0c/c481639b9c4e39df9dba5563561a0b0c2.gif)
![04第四講ADONET實(shí)體框架_第3頁(yè)](http://file4.renrendoc.com/view/c481639b9c4e39df9dba5563561a0b0c/c481639b9c4e39df9dba5563561a0b0c3.gif)
![04第四講ADONET實(shí)體框架_第4頁(yè)](http://file4.renrendoc.com/view/c481639b9c4e39df9dba5563561a0b0c/c481639b9c4e39df9dba5563561a0b0c4.gif)
![04第四講ADONET實(shí)體框架_第5頁(yè)](http://file4.renrendoc.com/view/c481639b9c4e39df9dba5563561a0b0c/c481639b9c4e39df9dba5563561a0b0c5.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第四講 ADO.NET 實(shí)體框架長(zhǎng)久以來(lái),程序員和數(shù)據(jù)庫(kù)總是保持著一種微妙的關(guān)系, 在商用應(yīng)用程序中, 數(shù)據(jù)庫(kù)一定是不可或缺的元件, 這讓程序員一定要為了連接與訪問(wèn)數(shù)據(jù)庫(kù)而去學(xué) 習(xí) SQL 語(yǔ)句,然而在眾多設(shè)計(jì)工具中,數(shù)據(jù)以對(duì)象的形式體現(xiàn)。 因此在業(yè)界中 有很多人 都在研究如何將 對(duì)象 模型 和數(shù)據(jù)庫(kù)集 成在 一起 ,對(duì)象關(guān)系對(duì)應(yīng)(Object-Relational Mapping) 的 技 術(shù) 就 是 由 此 而 生 , 像 Hibernate 或NHibernate都是這個(gè)技術(shù)下的產(chǎn)物,而微軟雖然有了 ADO.NE這 個(gè)數(shù)據(jù)訪問(wèn)的 利器,但卻沒(méi)有像 NHibernate 這樣的對(duì)象對(duì)應(yīng)工具
2、, 因此微軟在 .NET Framework 2.0 發(fā)展時(shí)期,就提出了一個(gè) ObjectSpace 的概念, ObjectSpace 可以讓應(yīng)用程 序可以用完全對(duì)象化的方法連接與訪問(wèn)數(shù)據(jù)庫(kù), 其技術(shù)概念 與 NHibernate 相當(dāng) 類似,然而 ObjectSpace 工程相當(dāng)大,在 .NET Framework 2.0 完成時(shí)仍無(wú)法全 部完成,因此微軟將 ObjectSpace 納入下一版本的 .NET Framework 中,并且再 加上一個(gè)設(shè)計(jì)的工具 (Designer) ,構(gòu)成了現(xiàn)在的 ADO.NET Entity Framework 。Entity Framework 利用了抽象
3、化數(shù)據(jù)結(jié)構(gòu)的方式,將每個(gè)數(shù)據(jù)庫(kù)對(duì)象都轉(zhuǎn) 換成應(yīng)用程序?qū)ο?(entity) ,而數(shù)據(jù)字段都轉(zhuǎn)換為屬性 (property) ,關(guān)系則轉(zhuǎn) 換為結(jié)合屬性 (association) ,讓數(shù)據(jù)庫(kù)的 E/R 模型完全的轉(zhuǎn)成對(duì)象模型,如 此讓程序設(shè)計(jì)師能用最熟悉的編程語(yǔ)言來(lái)調(diào)用訪問(wèn)。 而在抽象化的結(jié)構(gòu)之下, 則 是高度 集成與對(duì)應(yīng)結(jié) 構(gòu)的概 念層 、對(duì)應(yīng)層和儲(chǔ)存 層, 以 及支持 EntityFramework 的數(shù)據(jù)提供者 (provider) ,讓數(shù)據(jù)訪問(wèn)的工作得以順利與完整的進(jìn) 行。為概念模型賦予生命數(shù)據(jù)建模的一種由來(lái)已久且常見的設(shè)計(jì)模式是將數(shù)據(jù)模型分為三個(gè)部分:概 念模型、邏輯模型和物理模型。
4、概念模型定義要建模的系統(tǒng)中的實(shí)體和關(guān)系。 關(guān) 系數(shù)據(jù)庫(kù)的邏輯模型通過(guò)外鍵約束將實(shí)體和關(guān)系規(guī)范化到表中。 物理模型通過(guò)指 定分區(qū)和索引等存儲(chǔ)詳細(xì)信息實(shí)現(xiàn)特定數(shù)據(jù)引擎的功能。物理模型由數(shù)據(jù)庫(kù)管理員進(jìn)行優(yōu)化以改善性能, 而編寫應(yīng)用程序代碼的程序 員的工作主要限制為通過(guò)編寫 SQL 查詢和調(diào)用存儲(chǔ)過(guò)程來(lái)處理邏輯模型。概念 模型通常用作捕獲和傳達(dá)應(yīng)用程序的要求的工具, 常常以靜態(tài)關(guān)系圖的形式供項(xiàng)目早期階段查看和討論, 隨后被棄用。 許多開發(fā)團(tuán)隊(duì)會(huì)跳過(guò)概念模型的創(chuàng)建, 直 接從指定關(guān)系數(shù)據(jù)庫(kù)中的表、列和鍵開始工作。這使應(yīng)實(shí)體框架 , 可使開發(fā)人員查詢概念模型中的實(shí)體和關(guān)系,同時(shí)依賴于實(shí)體框 架 將這些操作
5、轉(zhuǎn)換為特定于數(shù)據(jù)源的命令,從而為概念模型賦予生命。用程序不再對(duì)特定數(shù)據(jù)源具有硬編碼的依賴性 。概念模型、存儲(chǔ)模型以及兩個(gè)模 型之間的映射以外部規(guī)范(稱為 實(shí)體數(shù)據(jù)模型(EDM)表示??梢愿鶕?jù)需要對(duì) 存儲(chǔ)模型和映射進(jìn)行更改, 而不需要對(duì)概念模型、 數(shù)據(jù)類或應(yīng)用程序代碼進(jìn)行更 改。存儲(chǔ)模型是特定于提供程序的, 因此可以在各種數(shù)據(jù)源之間使用一致的概念 模型。EDM由以下三種模型和具有相應(yīng)文件擴(kuò)展名的映射文件進(jìn)行定義。概念架構(gòu)定義語(yǔ)言文件 (.csdl) - 定義概念模型。存儲(chǔ)架構(gòu)定義語(yǔ)言文件 (.ssdl) - 定義存儲(chǔ)模型(又稱邏輯模型)。映射規(guī)范語(yǔ)言文件 (.msl) - 定義存儲(chǔ)模型與概念模型
6、之間的映射。 實(shí)體框架 使用這些基于 XML 的模型和映射文件將對(duì)概念模型中的實(shí)體和關(guān)系的創(chuàng)建、讀取、更新和刪除操作轉(zhuǎn)換為數(shù)據(jù)源中的等效操作。EDM甚至支持 將概念模型中的實(shí)體映射到數(shù)據(jù)源中的存儲(chǔ)過(guò)程。將對(duì)象映射到數(shù)據(jù)面向?qū)ο蟮木幊虒?duì)與數(shù)據(jù)存儲(chǔ)系統(tǒng)的交互提出了一個(gè)難題。 雖然類的組織通 ??杀容^接近地反映出關(guān)系數(shù)據(jù)庫(kù)表的組織, 但是擬合程度并不完美。 多個(gè)規(guī)范 化表通常對(duì)應(yīng)于單個(gè)類,類之間的關(guān)系并未按照表之間的關(guān)系一樣表示。例如, 若要表示某個(gè)銷售訂單的客戶,一個(gè) Order 類可使用包含對(duì) Customer 類實(shí)例 的引用的屬性,但是數(shù)據(jù)庫(kù)中的一個(gè) Order 表行包含的一個(gè)外鍵列(或列集)
7、 具有對(duì)應(yīng)于 Customer 表中的主鍵值的值。一個(gè) Customer 類可以具有名為Orders 的屬性,該屬性包含 Order 類的實(shí)例的集合,但是數(shù)據(jù)庫(kù)中的 Customer表不包含相應(yīng)的列。現(xiàn)有解決方案只能通過(guò)將面向?qū)ο蟮念惡蛯傩杂成涞疥P(guān)系表和列來(lái)嘗試彌 合這種通常稱為“阻抗不匹配”的差異。實(shí)體框架 沒(méi)有采用這種傳統(tǒng)方法,而 是將邏輯模型中的關(guān)系表、 列和外鍵約束映射到概念模型中的實(shí)體和關(guān)系。 這在 定義對(duì)象和優(yōu)化邏輯模型方面都增加了靈活性。實(shí)體數(shù)據(jù)模型 工具基于概念模型生成可擴(kuò)展數(shù)據(jù)類。 這些類是分部類, 可以通過(guò)開發(fā)人員添加的其他成員進(jìn)行 擴(kuò)展。為特定概念模型生成的類派生自一些基
8、類, 這些基類提供對(duì)象服務(wù)以將實(shí) 體具體化為對(duì)象以及跟蹤和保存更改。 開發(fā)人員可以使用這些生成的類以由導(dǎo)航 屬性關(guān)聯(lián)起來(lái)的對(duì)象的形式來(lái)處理實(shí)體和關(guān)系。訪問(wèn)和更改實(shí)體數(shù)據(jù)實(shí)體框架不僅僅是另一種對(duì)象關(guān)系映射解決方案,還從根本上使應(yīng)用程序可以訪問(wèn)和更改表示為概念模型中的實(shí)體和關(guān)系的數(shù)據(jù)。對(duì)象服務(wù)使用EDM 將對(duì) 概念模型中所表示的實(shí)體類型的對(duì)象查詢轉(zhuǎn)換為特定于數(shù)據(jù)源的查詢。 查詢結(jié)果 具體化為對(duì)象服務(wù)管理的對(duì)象。 實(shí)體框架 提供以下方式用于查詢 EDM 并返回對(duì) 象:LINQ to Entities - 提供語(yǔ)言集成查詢 (LINQ) 支持用于查詢?cè)诟拍?模型中定義的實(shí)體類型。Entity SQL-
9、 與存儲(chǔ)無(wú)關(guān)的 SQL 方言,直接使用概念模型中的實(shí)體并 支持諸如繼承和關(guān)系等 EDM 功能。 Entity SQL 可用于對(duì)象查詢和使用查詢生成器方法EntityClient 提供程序執(zhí)行的查詢??梢允褂?LINQ 風(fēng)格的查詢方法構(gòu)造 Entity SQL查詢。實(shí)體框架 中包含 EntityClient 數(shù)據(jù)提供程序。此提供程序管理連接,將 實(shí)體查詢轉(zhuǎn)換為特定于數(shù)據(jù)源的查詢, 并返回一個(gè)由對(duì)象服務(wù)用來(lái)將實(shí)體數(shù)據(jù)具 體化為對(duì)象的數(shù)據(jù)讀取器。 當(dāng)不需要對(duì)象具體化時(shí), 通過(guò)使應(yīng)用程序執(zhí)行 EntitySQL 查詢并使用返回的只讀數(shù)據(jù)讀取器,還可以像標(biāo)準(zhǔn) ADO.NET 數(shù)據(jù)提供程序 一樣使用 En
10、tityClient 提供程序。下圖說(shuō)明實(shí)體框架的使用過(guò)程:EDMErtdySQLEnUlYSQL冷洵LINQtoEntitieslEnurreraibleEntity Data ReaderEntit/Client較琪探供疣ifDBOataReaderAcauer *實(shí)體框架生成一個(gè)從ObjectC on text派生的類,該類表示概念模型中的實(shí)體容器。此對(duì)象上下文提供跟蹤更改以及管理標(biāo)識(shí)、并發(fā)和關(guān)系的功能。此類 還公開將插入、更新和刪除操作寫入數(shù)據(jù)源的 SaveChanges方法。與查詢類似,這些更改是由系統(tǒng)自動(dòng)生成的命令或由開發(fā)人員指定的存儲(chǔ)過(guò)程執(zhí)行的F面通過(guò)一個(gè)示例來(lái)說(shuō)明實(shí)體數(shù)據(jù)框架的
11、使用。1.、創(chuàng)建School數(shù)據(jù)庫(kù)和架構(gòu)在“文件”菜單上,指向“新建”,然后單擊“數(shù)據(jù)庫(kù)引擎查詢”。2.在“連接到數(shù)據(jù)庫(kù)引擎”對(duì)話框中,鍵入localhost 或本地SQL Server3.實(shí)例的名稱,然后單擊在查詢窗口中粘貼以下“連接”。Transact-SQL腳本,然后單擊“執(zhí)行”。(數(shù)據(jù)庫(kù)腳本見附件)倉(cāng)建 Course Man ager應(yīng)用程序1.在“文件”菜單上單擊“新建項(xiàng)目”。在“項(xiàng)目類型”窗格中,選擇“ Visual Basic ”或“Visual C# ”。在“模板”窗格中,選擇“ Windows窗體應(yīng)用程序”。4.5.6.在“文件屬性”窗格中,將“文件名”更改為CourseVi
12、ewer.vb對(duì)于項(xiàng)目名稱輸入CourseManager,然后單擊“確定”。 在 CourseManager 項(xiàng)目中,選擇默認(rèn)窗體 (Form1) 。CourseViewer.cs 。7.在“解決方案資源管理器”中,雙 擊 CourseViewer.vbCourseViewer.cs 以打開窗體。8.在“屬性”窗格中,將 Name 屬性更改為CourseViewer ,并將 Text性更改為 Course Viewer 。9.在“工具箱”中, 展開“公共控件”, 將復(fù)合框”控件拖到窗體上,后將該控件的名稱更改為 departmentList10.在“工具箱”中,將“按鈕”控件拖到窗體上,將此控
13、件的名稱更改為closeForm ,并將 Text 值更改為 Close 。11.在“工具箱”中,展開“數(shù)據(jù)”,將“ DataGridView”控件拖到窗體上,然后將該控件的名稱更改為 courseGridView 。12. 雙擊 closeForm 按鈕控件。13. 此時(shí)將打開窗體的代碼頁(yè)并創(chuàng)建 closeForm_Click 事件處理程序方法。14.在 closeForm_Click 事件處理程序方法中,鍵入以下用于關(guān)閉窗體的代碼:/ Close the form.this.Close();生成 School 實(shí)體數(shù)據(jù)模型1.在“解決方案資源管理器”中選擇 CourseManager 項(xiàng)目
14、,右鍵單擊,指 向“添加”,然后單擊“新建項(xiàng)”。2.在“模板”窗格中,選擇“ ADO.NET實(shí)體數(shù)據(jù)模型”。3.為模型名稱鍵入 School.edmx ,然后單擊“添加”。4.將顯示“實(shí)體數(shù)據(jù)模型向?qū)А钡拈_始頁(yè)。5.在“選擇模型內(nèi)容”對(duì)話框中, 選擇“從數(shù)據(jù)庫(kù)生成”。 然后,單擊“下止”步”。6.單擊“新建連接”按鈕。4.7.在“選擇數(shù)據(jù)源”對(duì)話框中,選擇您的數(shù)據(jù)源,然后單擊“繼續(xù)”。8.在“連接屬性”對(duì)話框中, 輸入服務(wù)器名稱, 選擇身份驗(yàn)證方法, 對(duì)于數(shù)據(jù)庫(kù)名稱,鍵入 School ,然后單擊“確定”。9.將使用您的數(shù)據(jù)庫(kù)連接設(shè)置更新“選擇您的數(shù)據(jù)連接”對(duì)話框。10. 確保選中“將 App
15、.Config 中的實(shí)體連接設(shè)置保存為 : ”,并且值設(shè)置為SchoolEntities 。然后,單擊“下一步”。11. 將顯示“選擇數(shù)據(jù)庫(kù)對(duì)象”對(duì)話框。12. 確保選中所有表和存儲(chǔ)過(guò)程,且“模型命名空間”的值為 SchoolModel ,然后單擊“完成”以完成向?qū)А?3. 在“解決方案資源管理器”中,雙擊 School.edmx 文件。此時(shí)將在“ADO.NET實(shí)體數(shù)據(jù)模型設(shè)計(jì)器”窗口中顯示 School模型。四、查詢實(shí)體和關(guān)聯(lián)在 School 數(shù)據(jù)庫(kù)中查詢系1.在 CourseViewer 窗體的代碼文件的開始處,添加以下 using (C#) 或Imports (Visual Basic)
16、 語(yǔ)句,以引用從 School 數(shù)據(jù)庫(kù)和實(shí)體命名空間中創(chuàng)建的模型。using System.Data.Objects;using System.Data.Objects.DataClasses;2.在 CourseViewer 窗體的分部類定義的頂部,添加以下用于創(chuàng)建ObjectContext 實(shí)例的代碼。/ Create an ObjectContext instance based on SchoolEntity.private SchoolEntities schoolContext;3.在 CourseViewer 窗體設(shè)計(jì)器中, 雙擊 CourseViewer 窗體。此時(shí)將打開窗體的
17、代碼頁(yè)并創(chuàng)建 courseViewer _Load 事件處理程序方法。在 courseViewer _Load 事件處理程序方法中, 復(fù)制并粘貼以下用于定義DataGridView 的代碼,執(zhí)行返回系科集合的查詢(按 Name 排序),然后將 Department 對(duì)象的集合綁定到 departmentList 控件。 / Initialize the ObjectContext.schoolContext = new SchoolEntities();/ Define a query that returns all Department objects and related/ Cours
18、e objects, ordered by name./ 查詢生成器方法ObjectQuery departmentQuery =schoolContext.Department.Include(Course).OrderBy(it.Name); /* 特別注意 include 的用法,后面的課程中將詳細(xì)介紹 * /LINQ to Entities 語(yǔ)法var departmentQuery1 = from department in schoolContext.Department.Include(Course) orderby department.Name select departme
19、nt;try / Bind the ComboBox control to the query, which is/ executed during data binding.this.departmentList.DataSource = departmentQuery1; this.departmentList.DisplayMember = Name;catch (Exception ex)MessageBox.Show(ex.Message);顯示所選系的課程在 CourseViewer 窗體設(shè)計(jì)器中, 雙擊 departmentList 控件。此時(shí)將創(chuàng)建 departmentList
20、_SelectedIndexChanged 事件處理程序方法。粘貼以下用于加載與所選系相關(guān)的課程的代碼。try/ Get the object for the selected department.Department department = (Department)this.departmentList.SelectedItem;/ Bind the grid view to the collection of Course objects/ that are related to the selected Department object. courseGridView.DataSo
21、urce = department.Course; courseGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMo de.AllCells);catch (Exception ex)MessageBox.Show(ex.Message);五、 插入和更新數(shù)據(jù)保存對(duì)對(duì)象所做的更改1. 在“工具箱”中,展開“公共控件”, 將“按鈕”控件拖到 CourseViewer窗體設(shè)計(jì)器,將控件的名稱更改為saveChanges,并將Text值更改為Update。雙擊 saveChanges 控件。事件處理程序方法。2. 在 CourseViewe
22、r 窗體設(shè)計(jì)器中,此時(shí)將創(chuàng)建 saveChanges_Click粘貼以下代碼,這些代碼將對(duì)象更改保存到數(shù)據(jù)庫(kù)中。tryint numChanges;/ Save object changes to the database, display a message, / and refresh the form.numChanges = schoolContext.SaveChanges();MessageBox.Show(numChanges.ToString() + change(s) saved to the database.);this.Refresh();catch (Exceptio
23、n ex)MessageBox.Show(ex.Message);通過(guò)釋放長(zhǎng)時(shí)間運(yùn)行的對(duì)象上下文關(guān)閉連接在 closeForm_Click 事件處理程序方法中,鍵入以下代碼。此代碼在關(guān)閉窗體之前釋放對(duì)象上下文。 / Dispose the object context. schoolContext.Dispose();4.4 對(duì)象服務(wù)對(duì)象服務(wù)是 實(shí)體框架 的一個(gè)組件,您可使用它來(lái)查詢、插入、更新和刪除 數(shù)據(jù),它表示為作為實(shí)體類型實(shí)例的強(qiáng)類型 CLR 對(duì)象。對(duì)象服務(wù)支持針對(duì) 實(shí)體 數(shù)據(jù)模型 (EDM) 中定義的類型進(jìn)行的語(yǔ)言集成查詢 (LINQ) 和 Entity SQL 查 詢。對(duì)象服務(wù)將返回
24、的數(shù)據(jù)具體化為對(duì)象, 并將對(duì)象更改傳播回?cái)?shù)據(jù)源。 它還提 供了跟蹤更改、將對(duì)象綁定到控件以及處理并發(fā)問(wèn)題的功能。對(duì)象服務(wù)由System.Data.Objects 和 System.Data.Objects.DataClasses 命名空間中的類 來(lái)實(shí)現(xiàn)。對(duì)象上下文ObjectContext 類是以對(duì)象(這些對(duì)象是 EDM 中定義的實(shí)體類型的實(shí)例) 的形式與數(shù)據(jù)進(jìn)行交互的主要類。 ObjectContext 類的實(shí)例封裝以下內(nèi)容:到數(shù)據(jù)庫(kù)的連接,以 EntityConnection 對(duì)象的形式封裝。 描述模型的元數(shù)據(jù),以 MetadataWorkspace 對(duì)象的形式封裝。在創(chuàng)建、更新和刪除操作
25、過(guò)程中跟蹤對(duì)象的 ObjectStateManager 對(duì)象。本講重點(diǎn)描述如何利用對(duì)象服務(wù)完成對(duì)象的添加、修改、刪除及并發(fā)控制, 至于如何利用對(duì)象服務(wù)完成查詢,我們放在下一講。對(duì)象上下文中的對(duì)象是實(shí)體類型的實(shí)例,表示數(shù)據(jù)源中的數(shù)據(jù)。在對(duì)象上下AdventureWorks 銷售 實(shí)體文中可以修改、 創(chuàng)建和刪除對(duì)象, 對(duì)象服務(wù)會(huì)跟蹤對(duì)這些對(duì)象所做的更改。 調(diào)用 SaveChanges 方法時(shí),對(duì)象服務(wù)會(huì)生成并執(zhí)行一些命令, 這些命令將對(duì)數(shù)據(jù)源執(zhí) 行等效的插入、更新或刪除語(yǔ)句。下面的程序基于 數(shù)據(jù)模型,請(qǐng)按以下步驟創(chuàng)建。1.在“項(xiàng)目” 菜單上單擊 “添加新項(xiàng)” 。2.3.在“模板”窗格中,選擇“AD
26、O.NET實(shí)體數(shù)據(jù)模型”。鍵入 AdventureWorks.edmx 作為模型名稱,然后單擊 “添加”將顯示“實(shí)體數(shù)據(jù)模型向?qū)А钡牡谝豁?yè)。在“選擇模型內(nèi)容” 對(duì)話框中, 選擇“從數(shù)據(jù)庫(kù)生成” 。然后,單擊“下止”步” 。5.單擊 “新建連接” 按鈕。6.在 “連接屬性” 對(duì)話框中, 鍵入服務(wù)器名稱, 選擇身份驗(yàn)證方法, 對(duì)于數(shù)據(jù)庫(kù)名稱,鍵入 AdventureWorks ,然后單擊 “確定” 。選擇您的數(shù)據(jù)連接” 對(duì)話框?qū)⒁阅臄?shù)據(jù)庫(kù)連接設(shè)置更新。7.確?!皩?App.Config 中的實(shí)體連接設(shè)置另存為 :” 復(fù)選框已選中,并且 其值設(shè)置為 AdventureWorksEntities 。
27、然后,單擊 “下一步” 。8.在“選擇數(shù)據(jù)庫(kù)對(duì)象” 對(duì)話框中, 清除所有對(duì)象, 展開“表” ,然后選擇以下表對(duì)象:AddressContactProductSalesOrderHeaderSalesOrderDetail9. 單擊 “完成” 以完成向?qū)АL砑?、刪除、修改對(duì)象在本 示 例 中, 對(duì) 象 查 詢 根 據(jù) 指定 的 SalesOrderID 返 回 單個(gè)SalesOrderHeader 對(duì)象。此訂單的狀態(tài)從 5 (已發(fā)貨)更改為 1 (在制品), 向訂單中添加一個(gè)新項(xiàng),并刪除第一個(gè)現(xiàn)有項(xiàng)。將調(diào)用 SaveChanges 方法以將 更改寫到數(shù)據(jù)庫(kù)中。然后,將訂單的結(jié)果狀態(tài)寫到控制臺(tái)。/
28、 Specify the order to update. int orderId = 43680;using (AdventureWorksEntities context = new AdventureWorksEntities()trySalesOrderHeader order =(from oh in context.SalesOrderHeaderwhere oh.SalesOrderID = orderId select oh).First();/ Change the status and ship date of an existing order. order.Status
29、 = 1;order.ShipDate = DateTime.Today;/ Load items for the order, if not already loaded.SalesOrderDetail 對(duì)象,兩者的關(guān)系/ 顯式加載和 SalesOrderHeader 對(duì)象相關(guān)的/ 為 1 對(duì)多的關(guān)系if (!order.SalesOrderDetail.IsLoaded)order.SalesOrderDetail.Load();/ Delete the first item in the order.context.DeleteObject(order.SalesOrderDetail
30、.First();/ Create a new item using the static Create method/ and add it to the order.實(shí)體框架 工具使用概念性架構(gòu)定義語(yǔ)言 層的代碼。當(dāng)生成數(shù)據(jù)類時(shí),將使用靜態(tài)/方法用于實(shí)例化對(duì)象并設(shè)置此類的不能為空的所有屬性。 文件中已應(yīng)用 Nullable=false 屬性 (Attribute)(CSDL) 文件以生成用于定義對(duì)象create 工廠方法生成每個(gè)類。此 此方法對(duì)于在 CSDL的每個(gè)屬/(Property) 都具有一個(gè)參數(shù)。 當(dāng)創(chuàng)建具有許多必需屬性的對(duì)象時(shí)使用此方法。 order.SalesOrderDeta
31、il.Add(SalesOrderDetail.CreateSalesOrderDetail(0,0, 2, 750, 1, (decimal)2171.2942, 0, 0,Guid.NewGuid(), DateTime.Today);/ Save changes in the object context to the database. int changes = context.SaveChanges();Console.WriteLine(changes.ToString() + changes saved!); Console.WriteLine(Updated item for
32、 order: + order.SalesOrderID.ToString();foreach (SalesOrderDetail item inorder.SalesOrderDetail.OrderBy(od=od.SalesOrderDetailID)Console.WriteLine(Item ID: + item.SalesOrderDetailID.ToString() + Product: + item.ProductID.ToString() + Quantity: + item.OrderQty.ToString();catch (UpdateException ex)Con
33、sole.WriteLine(ex.ToString();對(duì)象間的關(guān)系對(duì)象間的導(dǎo)航關(guān)系在建立一個(gè)新對(duì)象時(shí),需要特別注意。例如,建立一個(gè)新的 SalesOrderHeader 對(duì)象,它本身和 Contract 對(duì)象存在多對(duì)一的關(guān)系,和Address 對(duì)象存在多對(duì)一的關(guān)系, 和 SalesOrderDetail 對(duì)象存在一對(duì)多的關(guān)系。因此在添加一個(gè)新對(duì)象時(shí), 要考慮和新對(duì)象關(guān)聯(lián)的關(guān)系如何添加。 注意這些關(guān)系 在實(shí)體框架中體現(xiàn)為屬性導(dǎo)航, 在數(shù)據(jù)庫(kù)中則是實(shí)體間的外鍵關(guān)系。 實(shí)體框架一 般通過(guò)將子對(duì)象添加到父對(duì)象的 EntityConnection 集合來(lái)實(shí)現(xiàn)一對(duì)多的關(guān)系, 如: / 在 SalesO
34、rderHeader 中添加 SalesOrderDetail 對(duì)象 order.SalesOrderDetail.Add(item);/ 在 Contract 中添加 SalesOrderHeader 對(duì)象 customer.SalesOrderHeader.Add(order);多對(duì)一的關(guān)系怎樣添加呢, 由于父對(duì)象一般會(huì)在子對(duì)象的實(shí)體類中以一個(gè)屬 性的方式實(shí)現(xiàn),所有在只需要設(shè)置相應(yīng)的屬性就可以了。如:/ 在子對(duì)象 SalesOrderHeader 中設(shè)置父對(duì)象 Addressorder.Address = address;從上面的講述可以觀察到:customer.SalesOrderHea
35、der.Add(order); 和 order.Contact = customer;語(yǔ)句是等效的。程序示例見附件代碼中的 SaveObjectRelation() 方法。保存更改和管理并發(fā)實(shí)體框架 實(shí)現(xiàn) 開放式并發(fā)模型 。這意味著不對(duì)數(shù)據(jù)源中的數(shù)據(jù)保留鎖。但 是默認(rèn)情況下, 對(duì)象服務(wù)將對(duì)象更改保存到數(shù)據(jù)庫(kù)中, 而不檢查并發(fā)。 對(duì)于可能 高度并發(fā)的屬性 (Property) ,建議在概念層定義實(shí)體屬性 (Property) ,并設(shè)置在使用此屬性時(shí),對(duì)象服務(wù)會(huì)在屬性 (Attribute) ConcurrencyMode=fixed. 數(shù)據(jù)庫(kù)中檢查更改,然后將更改保存到數(shù)據(jù)庫(kù)。任何有沖突的更改都
36、會(huì)引發(fā)OptimisticConcurrencyException知識(shí)點(diǎn):什么是開放式并發(fā)控制在多用戶環(huán)境中,有兩種用于更新數(shù)據(jù)庫(kù)中數(shù)據(jù)的模型:開放式并發(fā)和保守 式并發(fā)。保守式并發(fā)涉及到鎖定數(shù)據(jù)源中的行, 以防止其他用戶因修改數(shù)據(jù)而影響當(dāng)前用戶。 在保守式模型中,當(dāng)用戶執(zhí)行會(huì)應(yīng)用鎖的操作時(shí),其他用戶將無(wú)法執(zhí)行可能與鎖發(fā)生沖突的操作,直到鎖所有者釋放鎖為止。此模型主要用于以下環(huán)境:對(duì)數(shù)據(jù)存在激烈爭(zhēng)用,使得用鎖保護(hù)數(shù)據(jù)的成本少于在發(fā)生并發(fā)沖突時(shí)回滾事務(wù)的成本。因此,在保守式并發(fā)模型中,更新行的用戶建立鎖。在該用戶完成更新并釋放鎖之前,其他任何用戶都無(wú)法更改鎖定行。 因此,如果鎖定時(shí)間將會(huì)比較短(例
37、如在以編程方式處理記錄時(shí)),最好實(shí)現(xiàn)保守式并發(fā)。如果用戶與數(shù)據(jù)進(jìn)行交互,會(huì)使記錄鎖定相對(duì)長(zhǎng)的時(shí)間,保守式并發(fā)并不是可伸縮的選項(xiàng)。對(duì)比之下,使用開放式并發(fā)的用戶在讀取行時(shí)不會(huì)鎖定該行。當(dāng)用戶要更新某行時(shí),應(yīng)用程序必須確定自讀取該行以來(lái),其他用戶是否更改了該行。放式并發(fā)通常用于對(duì)數(shù)據(jù)爭(zhēng)用較少的環(huán)境。 由于不需要鎖定任何記錄,開放式并發(fā)將會(huì)提高性能,因?yàn)殒i定記錄需要更多的服務(wù)器資源。另外,為了維護(hù)記錄鎖,需要與數(shù)據(jù)庫(kù)服務(wù)器保持持久連接。由于在開放式并發(fā)模型中并不會(huì)這樣,所以與服務(wù)器的連接可以在較少的時(shí)間內(nèi)為更多的客戶端提供服務(wù)。在開放式并發(fā)模型中,如果當(dāng)某用戶接收到來(lái)自數(shù)據(jù)庫(kù)的值后,另一用戶在該用戶
38、試圖修改該值之前即將其修改,則認(rèn)為發(fā)生了沖突。以下各表是根據(jù)一個(gè)開放式并發(fā)示例生成的。下午1:00,用戶1從具有以下值的數(shù)據(jù)庫(kù)中讀取一行:CustIDLastNameFirstName列名稱原始值當(dāng)前值數(shù)據(jù)庫(kù)中的值CustID101101101LastNameSmithSmithSmithFirstNameBobBobBobSmith101Bob下午1:01,用戶2讀取同一行。下午1:03,用戶2將FirstName從“ Bob更改為“ Robert ”并更新數(shù)據(jù)庫(kù)。列名稱原始值當(dāng)前值數(shù)據(jù)庫(kù)中的值CustID101101101LastNameSmithSmithSmithFirstNameBo
39、bRobertBob由于更新時(shí)數(shù)據(jù)庫(kù)中的值匹配用戶 2具有的原始值,因此更新成功。下午1:05,用戶1將“ Bob的名更改為“ James并試圖更新該行。列名稱原始值當(dāng)前值數(shù)據(jù)庫(kù)中的值CustID101101101LastNameSmithSmithSmithFirstNameBobJamesRobert此時(shí),由于數(shù)據(jù)庫(kù)中的值(“ JameS)不再匹配用戶1所預(yù)期的原始值,因此用戶 1 遇到了開放式并發(fā)沖突。 并發(fā)沖突僅向您表明更新失敗。 現(xiàn)在, 需要決定是用用戶 1 提供的更改來(lái)重寫用戶 2 提供的更改還是取消用戶 1 的更改。在高度并發(fā)情況下進(jìn)行更新時(shí),建議經(jīng)常調(diào)用Refresh 。在調(diào)用
40、 Refresh時(shí), RefreshMode 將控制傳播更改的方式。如果使用 StoreWins 選項(xiàng),則對(duì)象 服務(wù)將使用數(shù)據(jù)庫(kù)中的相應(yīng)值在對(duì)象緩存中重寫所有數(shù)據(jù)。相反,如果使用ClientWins 選項(xiàng),則將使用數(shù)據(jù)源中的最新值替換緩存中的原始值。這樣,通 過(guò)消除緩存數(shù)據(jù)的更改與數(shù)據(jù)源中相應(yīng)數(shù)據(jù)的更改之間的沖突, 可以確保對(duì)象緩 存中更改過(guò)的所有數(shù)據(jù)都可以成功地保存回?cái)?shù)據(jù)源。對(duì)象服務(wù)跟蹤已在緩存中對(duì)對(duì)象進(jìn)行的更改。調(diào)用 SaveChanges 方法時(shí), 對(duì)象服務(wù)嘗試將更改合并回?cái)?shù)據(jù)源。 如果對(duì)象緩存中的數(shù)據(jù)更改與對(duì)象添加到緩 存后或在緩存中刷新后的數(shù)據(jù)源更改發(fā)生沖突, SaveChanges
41、 會(huì)失敗,并引發(fā)OptimisticConcurrencyException 。 這 會(huì) 導(dǎo) 致 整 個(gè) 事 務(wù) 回 滾 。 如 果 發(fā) 生OptimisticConcurrencyException ,應(yīng)通過(guò)調(diào)用 Refresh 并指定是否解決沖突通過(guò)將數(shù)據(jù)保存到對(duì)象數(shù)據(jù) (ClientWins) 或通過(guò)使用數(shù)據(jù)源數(shù)據(jù)更新對(duì)象緩存 (StoreWins) )來(lái)處理該異常,如下面的示例所示: try/ Try to save changes, which may cause a num = context.SaveChanges();Console.WriteLine
42、(No conflicts. + num.ToString() + updates saved.);catch (OptimisticConcurrencyException)/ Resolve the concurrency conflict by refreshing the / object context before re-saving changes. context.Refresh(RefreshMode.ClientWins, orders);/ Save changes.context.SaveChanges();Console.WriteLine(OptimisticConcurrencyException + handled and changes saved); 以下示例說(shuō)明實(shí)體框架處理開放式并發(fā)的過(guò)程:1.打開 Adventu
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 汽車租賃書面合同書
- 聯(lián)保借款標(biāo)準(zhǔn)合同
- 2025小麥購(gòu)銷合同樣本
- 個(gè)人借款合同合同英文范本
- 提升銷售技巧的培訓(xùn)課程
- 2024年5G通信基礎(chǔ)設(shè)施建設(shè)合同
- 2025復(fù)件(I)復(fù)件建設(shè)工程勘察設(shè)計(jì)合同1
- 原材料購(gòu)銷合同范本
- 2025養(yǎng)老服務(wù)合同范文大全
- 專用教育教學(xué)設(shè)備采購(gòu)合同書
- 煙草局合同范例
- AutoCAD2024簡(jiǎn)明教程資料
- 紅色大氣財(cái)務(wù)報(bào)銷流程培訓(xùn)課件
- 新能源電站單位千瓦造價(jià)標(biāo)準(zhǔn)值(2024版)
- 原子結(jié)構(gòu) 教學(xué)設(shè)計(jì) 高二化學(xué)人教版(2019)選擇性必修2
- 2024年2孩離婚協(xié)議書模板2024電子版
- 浪潮銷售在線測(cè)評(píng)題
- 高中語(yǔ)文:選擇性必修中冊(cè)第三單元拓展閱讀
- 耳穴壓豆課件
- 2023年江蘇省南京市中考化學(xué)真題(原卷版)
- 2023年湖北省襄陽(yáng)市中考數(shù)學(xué)真題(原卷版)
評(píng)論
0/150
提交評(píng)論