以前的小項目作完了,到了總結經驗和更新學習筆記的時間了。開始正題以前先囉嗦一下,對以前的學習目標進行一個調整:「根據代碼生成表」與「生成數據庫腳本和變動腳本」合併爲「Code First模式平常使用篇」,增長如今這篇「錯誤彙總」,增長「Code First模式與其餘模式混合使用與Fluent API篇」,「生成視圖」由於此次在項目中沒有使用,最後研究後再寫出來。
經過項目實戰,以爲EF並不像以前想象中的這麼容易上手。問題不是EF設計的很差,EF使用起來其實至關便捷,多數數據庫操做一兩行代碼就能搞定,基本不須要本身寫SQL。問題主要有兩點:EF的學習資源基本侷限在官方網站,由於EF更新相對比較快,各類書籍資料更不上很正常;再就是EF初學者很容易遇到問題,各類問題……這篇文章的主要目的就是跟你們分享項目的整個過程當中遇到的問題。
此次項目中遇到的問題主要能夠分爲如下幾類:
1. 配置文件問題
2. Visual Studio編譯和程序集問題
3. 數據庫問題
4. 代碼問題(導航屬性外鍵關聯,linq中的Convert)
其中第4點,代碼問題可能的狀況很是多,只說一下我遇到的一兩個問題。
1. 配置文件問題
配置文件的問題在
第二篇學習筆記中提到了,這裏只作簡單的總結。
配置文件涉及的問題可能有以下一些狀況:
1. 數據庫鏈接字符串配錯了,常見的有數據庫服務器名稱、數據庫名拼寫錯誤。
2. 數據庫鏈接字符串裏的用戶名密碼沒有登陸權限或者密碼過時了了。
3. 數據庫鏈接字符串配置項的name值與Context的名稱不一致找不到。
4. EF會使用VS中設置的啓動項目的配置文件(Web.config或App.config)工做,而啓動項目中恰好沒有正確配置EF
2. Visual Studio編譯和程序集問題
在項目開發過程當中有一次用svn客戶端的清理功能把全部忽略的文件清理掉了,包括編譯生成的obj和Bin文件夾。再次編譯時發現WCF端方法報錯:
沒法爲具備固定名稱「System.Data.SqlClient」的 ADO.NET 提供程序加載在應用程序配置文件中註冊的實體框架提供程序類型「System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer」。請確保使用限定程序集的名稱且該程序集對運行的應用程序可用。有關詳細信息,請參閱 http://go.microsoft.com/fwlink/?LinkId=260882。
通過查找,發現是WCF項目的Bin文件夾下缺乏EntityFramework.SqlServer.dll這個程序集致使的。多是本身EF使用有問題,也多是EF的一個bug。我在Db層引用了這個程序集,而後在WCF項目中引用了Db項目,最後Db引用的程序集卻沒有拷貝到WCF中。
3. 數據庫問題
數據庫可能出的問題也挺多,若是項目的數據庫不是項目獨佔,而是共用的,有些表多是共享的。好比此次作的這個項目,由於是一個工具性質的項目,依賴另外一個正在開發的系統的幾張表。其實這種用法就會有不少問題,首先這是一種後面要介紹到的Code First和Database First兩種模式的混合模式。其次兩個系統之間的耦合度十分高,對方系統表若是有必定的變動就會影響到系統,當時爲了節省接口開發的工做量就直接採用數據庫訪問了。
說了這麼多,第一個可能遇到的問題就是數據庫結構發生了變化,跟代碼裏的實體不一致了,好比表名或字段名發生了變化。
另外一個問題是數據庫的帳號權限有問題,開發的時候不少人可能會使用sa帳號登陸數據庫,開發的時候一點問題也沒有,但是到部署的時候,就可能出現這樣那樣的問題。昨天客戶在部署系統,告訴我部署出問題部署不了,遠程看了下,發現了兩個問題,其中一個問題就是數據庫帳號權限的問題。客戶建的帳號裏只有一個public權限,沒有DataReader和DataWriter,這確定是不行的。由於客戶堅持另外一個系統也用的這個帳號,能正常訪問。我將信將疑親自試了一把,沒有DataReader和DataWriter的狀況下,帳號連到SSMS裏一張表也看不見,查詢直接報錯,找不到對象,加上DataReader就立馬能查詢了,但是插入、更新和刪除都不行,加上DataWriter後正常。
開發過程當中還遇到過另外一個系統的負責人將Code First遷移用到的__MigrationHistory表刪掉了,致使沒法新增遷移的狀況。這個表刪掉了,系統仍是能正常工做的,只是更新數據庫和新增遷移時會很麻煩,我是將我本身的表全刪掉,從新更新數據庫,而後才能新增遷移的。這樣測試數據就全丟失了,好在不重要。後來通過查詢資料,得知EF6開始,能夠自定義__MigrationHistory的名稱了,有興趣能夠看msdn上的
這篇文章。
另外還據說數據庫版本是2000使用EF會有問題,也有說2005也可能有問題的,此次沒有驗證過,由於開發時候用的是SQL Server 2008r2。
4. 代碼問題
剛使用EF的時候對導航屬性並無太多概念,在導航屬性上沒有加virtual關鍵字,在使用過程當中發現導航屬性都沒有加載出來。原來不加virtual關鍵字就不會啓用延遲加載特性,不過能夠手動使用積極加載(Eagerly Loading)的方式讓EF加載導航屬性,並且是非延遲的。只須要使用DbQuery<TResult>的Include方法便可。這一點有時可能須要用到。有興趣能夠參考msdn上的
這篇文章。 另外一個問題則是在使用EF時,覺得EF能夠像之前使用的linq表達式同樣隨意寫,在有些條件判斷的地方用到了System.Convert下的函數,結果在運行時就報錯了。由於EF是要把linq表達式轉換爲sql語句的,而System.Convert和其餘一些函數是不支持轉換爲sql語句的,所以在使用ef的時候須要注意,若是有須要,能夠事先轉換好。 暫時記下的問題就是這些,之後發現新的問題再補充。