2012-05-05 195 views
3

您好我開發了一個使用SQL Compact和EF4的C#預算應用程序,我通過VS2010實體數據模型創建了EF模型。這一切都很好。不過,我正在考慮開發iPhone應用程序來支持現金交易,並認爲在兩個平臺上都支持後端數據庫會更好。在創建SQLite數據庫並創建一個新模型後,當我嘗試通過模型中的導航屬性訪問引用的數據時遇到了問題。當試圖顯示被引用表的屬性時,我得到一個NullReferenceException。實體框架,SQLite和延遲加載

當使用下面的代碼,我得到最後一行除外:

BudgetEntities budget = new BudgetEntities(); 
var accounts = budget.BankAccounts.ToList(); 

foreach (BankAccount a in accounts) 
{ 
    Console.WriteLine("Name:" + a.Description); 
    Console.WriteLine("Number:" + a.AccountNumber); 
    Console.WriteLine("Type:" + a.BankAccountType.AccountType); //Exception occurs here. 
} 

奇怪的是,該異常不會在這個例子中發生。我不確定發生了什麼事?

BudgetEntities budget = new BudgetEntities(); 
var accoutTypes = budget.BankAccountTypes; 

var account = new BankAccount(); 
account.ID = Guid.NewGuid(); 
account.AccountTypeID = accoutTypes.First(t => t.AccountType.StartsWith("Credit")).ID; 
account.BSB = "3434"; 
account.AccountNumber = "32323"; 
account.Description = "Test"; 
account.TrackingAccount = true; 

budget.AddObject("BankAccounts", account); 
budget.SaveChanges(); 
var accounts = budget.BankAccounts.ToList(); 

foreach (BankAccount a in accounts) 
{ 
    Console.WriteLine("Name:" + a.Description); 
    Console.WriteLine("Number:" + a.AccountNumber); 
    Console.WriteLine("Type:" + a.BankAccountType.AccountType); //Exception doesn't happen. 
} 

這只是一個簡單的例子,我知道我可以通過添加.INCLUDE(「BankAccountTypes」),以查詢解決它,但是我有一個是被創建對象,其中包括從引用的性質相當複雜的其他查詢在查詢中的對象,我不太清楚如何解決這個問題。

編輯: 在項目之間休息後,我已經回到這個問題,我終於解決了我的問題。它與代碼無關。這是與數據。我已經通過轉儲和加載將SQL Compact數據庫轉換爲SQLite,並且我的Guid列數據的語法錯誤。我插入GUID作爲「7cee3e1c-7a2b-462d-8c3d-82dd6ae62fb4」時,它應該是x'7cee3e1c7a2b462d8c3d82dd6ae62fb4'

希望我拉出過這個問題的工作將重新長出頭髮:)

謝謝每個人都爲你輸入。

+0

這兩個示例在哪裏運行?網絡服務器?控制檯程序?當你在同一個地方運行兩個例子會發生什麼? – tzerb

+0

這兩個示例運行在一個簡單的控制檯應用程序中,以嘗試確定發生了什麼。 – ruskie

回答

0

確保BankAccountType屬性在BudgetEntities中聲明爲虛擬。

+0

我試過這個,但我仍然得到相同的錯誤。 BudgetEntities是由VS2010自動生成的。我不明白爲什麼它使用SQL壓縮數據庫工作得很好,使用自動生成的實體而不是SQLite。你有什麼其他的建議? – ruskie

2

在第二個例子中您的代碼段開頭:

var accoutTypes = budget.BankAccountTypes; 

這會將所有銀行帳戶類型的應用程序,你不需要延遲加載了(EF會自動識別這些實體已經加載並修正與銀行賬戶的關係)。

首先檢查您的賬戶類是否爲動態代理(只需在調試器中檢查a的類型)。如果不是你在類定義中犯了一些錯誤,那麼延遲加載將不起作用。接下來檢查您的上下文實例是否啓用延遲加載(budget.ContextOptions.LazyLoadingEnabled屬性)。

+0

我試着在第一個例子中添加代碼片段,我仍然得到異常。我還檢查了帳戶類,它不是動態代理,即使ContextOptions.ProxyCreationEnabled設置爲true並且ContextOptiions.LazyLoadingEnabled也處於打開狀態。 – ruskie

+0

我已經做了一些進一步的測試,並比較了.edmx和.designer。爲SQL Compact DB和SQLite DB創建的cs,本質上它們是相同的,但SQLite似乎並未加載引用的實體。我開始認爲這是SQLite的限制。你認爲這可能是這樣嗎? – ruskie

+0

如果使用SQLite提供程序(system.data.sqlite),可能會出現一些問題,因爲該提供程序的目標是.NET 3.5和EFv1,因此EFv4的某些功能不必可用。透明的延遲加載是EFv4的特性,但我相信它不應該依賴於提供程序,所以它應該仍然可以像預期的那樣與舊的SQLite提供程序一起工作。您可以嘗試使用Devart的dotConnect for SQLite並驗證它是否與提供程序有關。 –