謝日星武漢軟件工程職業(yè)學(xué)院,湖北武漢 430205
ADO.NET Entity Framework是微軟以ADO.NET為基礎(chǔ)所發(fā)展出來(lái)的對(duì)象關(guān)系對(duì)應(yīng)(O/R Mapping)解決方案。Entity Framework以Entity Data Model(EDM)為主,利用抽象化數(shù)據(jù)結(jié)構(gòu)方式,將數(shù)據(jù)庫(kù)對(duì)象轉(zhuǎn)換成應(yīng)用程序?qū)ο?,?kù)表字段轉(zhuǎn)換為屬性,并系轉(zhuǎn)換為關(guān)聯(lián)系統(tǒng),把數(shù)據(jù)庫(kù)的E/R模型轉(zhuǎn)換成對(duì)象模型,使開(kāi)發(fā)人員通過(guò)對(duì)概念應(yīng)用程序模型編程來(lái)創(chuàng)建數(shù)據(jù)訪問(wèn)應(yīng)用程序,以此降低面向數(shù)據(jù)的應(yīng)用程序所需要的開(kāi)發(fā)量,并減輕系統(tǒng)維護(hù)工作。
Entity Framework技術(shù)的應(yīng)用中,可針對(duì)數(shù)據(jù)庫(kù)中各個(gè)表按照1:1映射生成模型和映射信息,在代碼中直接對(duì)表中數(shù)據(jù)進(jìn)行增、刪、改、查操作。但在實(shí)際應(yīng)用中,這種簡(jiǎn)單的處理方式不利于進(jìn)一步降低程序開(kāi)發(fā)工作量,部分情況還違背了“程序開(kāi)發(fā)以應(yīng)用為中心的概念模型來(lái)工作”的理念,對(duì)象的概念不清晰。為此,對(duì)幾種常用的數(shù)據(jù)庫(kù)情景的建模方法進(jìn)行介紹。
在帶有有效栽花的多對(duì)多關(guān)系數(shù)據(jù)庫(kù)中,關(guān)系表除了主鍵外,還有其他數(shù)據(jù)字段。在這種關(guān)系中,直接把表映射到實(shí)體模型中,兩實(shí)體表自動(dòng)創(chuàng)建對(duì)應(yīng)的實(shí)體類(lèi)型,而關(guān)系表也被映射成為一實(shí)體類(lèi)型,在此實(shí)體類(lèi)型中除了原有屬性名,還有對(duì)應(yīng)兩實(shí)體表的導(dǎo)航屬性,可分別通過(guò)1對(duì)多關(guān)系進(jìn)行對(duì)象導(dǎo)航。
對(duì)于分類(lèi)表之類(lèi)的自引用表,把表映射成為實(shí)體類(lèi)型后,其中將包含兩個(gè)導(dǎo)航屬性,分別對(duì)應(yīng)父、子對(duì)象,其中父對(duì)象為1端,多端為子對(duì)象集合,因此分別把1端改名為父端名稱如ParentCategory,多端改名為子對(duì)象集合名稱如SubCategories。由此兩導(dǎo)航屬性可方便地訪問(wèn)到對(duì)應(yīng)對(duì)象。
在數(shù)據(jù)庫(kù)設(shè)計(jì)過(guò)程中,當(dāng)一個(gè)實(shí)體的數(shù)據(jù)由于各種原因?yàn)榉指钤诓煌碇?,而程序開(kāi)發(fā)需要把實(shí)體所有數(shù)據(jù)集合在一個(gè)實(shí)體類(lèi)型中。對(duì)于這種跨表實(shí)體的情況,建模時(shí)首先把所有的表都映射到實(shí)體模型中,然后調(diào)整實(shí)體類(lèi)型,把主要表之外的其它表映射實(shí)體類(lèi)中除主鍵對(duì)應(yīng)屬性外的所有屬性復(fù)制到主要表映射實(shí)體類(lèi)型中,然后刪除主要表映射實(shí)體類(lèi)型中的所有導(dǎo)航屬性和其它表實(shí)體類(lèi)型,在刪除其它表實(shí)體類(lèi)型時(shí),不刪除映射存儲(chǔ)模型中的表,最后,在剩下的這一個(gè)表映射實(shí)體類(lèi)型中,添加復(fù)制得到的所有屬性的映射關(guān)系,分別映射到對(duì)應(yīng)的表中的列。在實(shí)體操作過(guò)程中,映射關(guān)系能自動(dòng)分別處理不同表中的對(duì)應(yīng)數(shù)據(jù)。
在表中如果有部分字段內(nèi)容較多并且不常使用,為提高程序性能,訪問(wèn)表時(shí),一般只訪問(wèn)表中的部分字段,為此,建模時(shí)必須把表分割成多個(gè)實(shí)體。首先把表映射成一般實(shí)體類(lèi)型,然后在設(shè)計(jì)器中創(chuàng)建新實(shí)體類(lèi)型,添加對(duì)應(yīng)原表中主健的屬性,再把原映射實(shí)體類(lèi)型中不需要的屬性通過(guò)“剪切/粘貼”方法移動(dòng)到新實(shí)體類(lèi)型中,并把新實(shí)體類(lèi)型中的所有屬性映射到原表對(duì)應(yīng)字段,然后在原實(shí)體類(lèi)型中添加到新實(shí)體類(lèi)型的1對(duì)1(或1對(duì)0.1)關(guān)聯(lián)關(guān)系,最后,在添加以新實(shí)體類(lèi)型為主體的到原實(shí)體類(lèi)型的引用約束。通過(guò)實(shí)體類(lèi)型訪問(wèn)數(shù)據(jù)時(shí),兩實(shí)體類(lèi)型對(duì)象分別訪問(wèn)其屬性對(duì)應(yīng)的字段數(shù)據(jù)。
數(shù)據(jù)庫(kù)建模完成后,對(duì)于有些表存儲(chǔ)另一表中額外信息的情況,可以針對(duì)這些表建立派生的類(lèi)體系結(jié)構(gòu)。首先,把所有表映射到實(shí)體模型中,分別映射成一個(gè)實(shí)體類(lèi)型,然后刪除實(shí)體類(lèi)型之間的關(guān)聯(lián),再為基類(lèi)(Business)添加繼承,分別設(shè)置派生類(lèi)為Retails和eCommerces,再刪除派生類(lèi)中的BusinessId屬性,則根據(jù)表的結(jié)構(gòu)完成類(lèi)的體系結(jié)構(gòu)建模,對(duì)Retails和eCommerces類(lèi)型對(duì)象的操作會(huì)自動(dòng)訪問(wèn)庫(kù)表Retails、eCommerces及對(duì)應(yīng)的Business表中對(duì)應(yīng)記錄。
對(duì)于常見(jiàn)的辦公自動(dòng)化系統(tǒng)數(shù)據(jù)庫(kù),由于員工類(lèi)型不同,而薪水制度不同,其中EmployeeType值為1則為臨時(shí)工,薪水按小時(shí)計(jì)算,Wage字段記錄其每小時(shí)薪水,Salary字段為無(wú)效數(shù)據(jù),如果EmployeeType值為2則為正式員工,薪水按月計(jì)算,Salary字段記錄其每月薪水,Wage字段數(shù)據(jù)無(wú)效。為更好地實(shí)現(xiàn)在向應(yīng)用編程,分別建立臨時(shí)工和正式員工兩種類(lèi)型,但兩種類(lèi)型的數(shù)據(jù)都保存在Employees表中。建模過(guò)程首先把Employees表映射到實(shí)體模型中,成為Employees類(lèi),然后添加新實(shí)體HourlyEmployee,指定基類(lèi)為Employees,然后通過(guò)“剪切/粘貼”把Employees中的Wage屬性移動(dòng)到HourlyEmployee中,用同樣的方法添加實(shí)體FullTimeEmployee類(lèi)型;再在HourlyEmployee實(shí)體中,添加映射條件:“EmployeeType = 1”,在FullTimeEmployee實(shí)體中添加映射條件:“EmployeeType = 2”,然后設(shè)置Employees類(lèi)型為抽象類(lèi),并刪除其中的EmployeeType屬性,則HourlyEmployee和FullTimeEmployee自動(dòng)處理EmployeeType字段的值,并能自動(dòng)根據(jù)記錄創(chuàng)建對(duì)應(yīng)類(lèi)型的對(duì)象。
POCO技術(shù)要求盡可能的應(yīng)用簡(jiǎn)單的類(lèi),以實(shí)現(xiàn)類(lèi)型的獨(dú)立性,本文所討論的Entity Framework建模方法則常常需要把表進(jìn)行分割建?;蚪M合建模,在某些情況下將導(dǎo)致類(lèi)的體系結(jié)構(gòu)更為復(fù)雜,但卻使程序開(kāi)發(fā)更為符合業(yè)務(wù)的現(xiàn)實(shí)情況,能更充分地利用Entity Framework技術(shù)的各種技術(shù)優(yōu)勢(shì)。
[1]微軟公司著.VS2010 MSDN.