Entity Framework的儲存模型切換實踐

來源:互聯網
上載者:User

  最近做一個項目,裡面需要同時支援Sql Server和SQLite。考慮到Entity Framework雖然目前還有諸多不足,但是基本上滿足於我的項目的要求,加上,也希望做一個嘗試,畢竟,雖然使用過去的技術和手段可能更可靠、更熟練、風險更低,但是,在技術行業,不能止步不前,如果某種新技術有你需要的某些特性,並且你認為值得嘗試,那就應該出手試試,雖然嘗試可能會失敗(以及不得不吞下失敗產生的苦果),但是如果成功,其帶來的好處也是很大的,也代表著你又往前邁進了一步。對於Entity Framework我也是新手,如果各位朋友發現文中有什麼可以改進的地方或者不正確的地方,歡迎指點。

 

  廢話不多說了。切入正題。Entity Framework需要三種檔案支援:CSDL(概念結構定義語言)、SSDL(存放結構定義語言)、MSL(對應規格語言),以及,一個據此產生的類檔案(這裡我們不研究這個類檔案)。從這種結構上看,EF是完全支援上層穩定的概念架構與底層具體可變動的儲存架構之間的獨立和分離的。但通常我們利用VS的設計器只能產生一個單獨的.edmx檔案,其中包含了CSDL、SSDL和MSL的內容,而本質上,它們3個是完全可以獨立成3個檔案的。對於我們當前的目標,我們需要把SSDL從.edmx檔案中剝離出來,並創立分別針對於Sql Server和SQLite的SSDL。

 

下面詳述一下我的做法。

1、根據Sql Server中的表、視圖結構,建立SQLite資料庫

  由於之前已經Sql Server上已經有了相關的表和視圖,因此以Sql Server為模板,建立SQLite資料庫,並在SQLite資料庫中建立與Sql Server中的表和視圖幾乎完全一樣的表和視圖。之所以說“幾乎完全一樣”,是因為SQLite中的類型系統與Sql Server中的差別很大。但是因為我沒有用到Sql Server中太特別的類型,因此這個問題的解決相對容易一些。我從Sql Server中產生表和視圖的指令碼,然後修改一下讓SQLite可以識別和執行。主要的修改包括,去掉“dbo”架構的指定,將自增識別欄位主鍵的聲明“int identity(1,1) primary key”改為“integer primary key autoincrement”,後者是SQLite中自增列主鍵的聲明語句,對於其他簡單類型,比如varchar/nvarchar, bit, money等等類型則保留原有的聲明不變,這些類型雖然SQLite並不“支援”,但是執行的時候並不會出錯,而且利用“.schema”命令查詢表架構時,這些類型的聲明是被保留的(後面在產生針對SQLite的EDM的時候,似乎也說明這些型別宣告產生了正面作用),另外,有一點,這次我沒有用到DateTime類型,因此無法斷定2種資料庫對它的支援的差別。SQLite的類型系統的特點是,動態性,雖然你建立表的時候可以指定某種“類型”,但是你完全可以向一個“int”列插入一個字串。最後,我沒有在SQLite中建立任何外鍵約束,雖然SQLite支援外鍵,但是為了簡化複雜性(畢竟這是我的初次嘗試),就犧牲一些“完整性”吧。

   由於保證了SQLite中的表和視圖與Sql Server中的完全一致(除了類型上的固有差別),因此,可以保證兩者在建立EDM的時候,其CSDL和MSL是完全相同的。

2、依據Sql Server建立EDM

  具體方法就和我們平常做的一樣。利用VS比較強大的設計器,從Sql Server中產生模型,並且建立好各個實體之間的Association。經過這一步,我們會得到一個.EDMX檔案以及一個對應的類檔案。

 

3、建立針對Sql Server的SSDL檔案

  用XML編輯器開啟上面產生的.EDMX檔案,可以很清楚的分辨出SSDL、CSDL、MSL三部分。我們把“<edmx:StorageModels>”節點下的<Schema>節點的所有內容Copy出來,就是中黃色標記出來的那部分:

 

然後建立一個尾碼名為.SSDL的XML檔案,把Copy出來的Schema元素粘貼進去。儲存。就可以了。

 

3、建立針對SQLite的SSDL檔案

  這一步有2種辦法:

  • 將針對Sql Server的SSDL檔案複製一份過來,然後將其修改成符合SQLite的要求。主要是去掉一些SQLite不支援的東西,比如,對於Schema="dbo"這樣的聲明。以及,修改Schema元素的Provider屬性和ProviderManifestToken屬性。前者需要修改為"System.Data.SQLite",後者修改為“ISO8601”(為何改成這2個值?看到後面就會知道了)
  • 利用VS的設計器重新針對SQLite資料庫產生一份EDMX檔案,然後抽取其中的SSDL定義。

  我採用的是第二種方法。 這裡需要用到針對SQLite的ADO.NET提供者,即System.Data.SQLite。這個東西可以從以下連結找到:http://sqlite.phxsoftware.com/,真正的在http://sourceforge.net/projects/sqlite-dotnet2/files/

下載完成之後,可以安裝,然後就可以在項目中引用System.Data.SQLite並利用設計器建立針對SQLite資料庫的EDM。建立和提取SSDL的內容與針對SQL Server的完全一樣,不再贅述,由此,我們可以得到一個針對SQLite的SSDL檔案,其中Schema元素的Provider屬性值是System.Data.SQLite,而ProviderManifestToken屬性是ISO8601。

  這裡還需要指出的一點是,後來在測試的時候,發現運行失敗,原因是,在SSDL中存在不同的表/實體類型中引用和被引用的欄位(外鍵欄位)Type屬性不一致的情況,比如假設Company類型的CompanyID欄位在Company類型中的type是integer,但是在引用它的Employee類型中的CompanyID欄位的type是int,在這裡,比如把它們2個統一為int或integer才可以。

4、通過修改連接字串來切換不同的SSDL

  在我的項目中,我將這2個SSDL分別作為2個不同的程式集的資源內嵌到程式集中。然後通過修改連接字串來切換到某個SSDL。連接字串看起來是這樣的:

metadata=res://GE/GTDP.GTDEDM.csdl|res://LiteTDP/LiteTDP.GTDEDM.ssdl|res://GE/GTDP.GTDEDM.msl;provider=System.Data.SQLite;provider connection string=&quot;Data Source=D:\Practice\SQLite\Ricky.db;&quot; 

注意連接字串中對於CSDL、SSDL、MSL的指定,都指定到具體程式集的相關資源,其中黃色底色部分指定了使用SQLite的SSDL,而CSDL和MSL則直接使用了第二步中產生的EDMX中的內容。

 

補充:

  在第二步中產生的EDMX被完整的保留下來,這樣,仍然可以隨時利用設計器開啟和操作。而針對SQLite產生的EDMX在提取需要的SSDL之後被我刪掉了。當然了,是留是刪,完全看需要,和,嗯,心情了。呵呵。

  很久沒有寫東西,都不會說話了,如果讀起來彆扭,請多包涵了。 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.