2012-05-05 2 views
3

Привет Я разработал приложение C# бюджета с использованием SQL Compact и EF4, я создал модель EF через шаблон VS2010 Entity Data Model. Все работает очень хорошо. Тем не менее, я рассматриваю возможность разработки приложения для iPhone для поддержки транзакций с наличными деньгами и думал, что было бы лучше иметь поддержку БД на обеих платформах. После создания SQLite DB и создания новой модели я столкнулся с проблемой при попытке доступа к ссылочным данным через свойства навигации в моей модели. Я получаю исключение NullReferenceException при попытке отобразить свойство ссылочной таблицы.Entity Framework, 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») на запрос, однако у меня есть другие вопросы, которые являются довольно сложными, что создается объект, который включает в себя свойства из ссылки объект в запросе, и я не совсем уверен, как обойти эту проблему для них.

EDIT: После перерыва между проектами я вернулся к этой проблеме, и я, наконец, решил свою проблему. это не имело никакого отношения к коду. Это было с данными. Я преобразовал базу данных SQL Compact в SQLite с помощью дампа и загрузки и неправильно использовал синтаксис для данных столбца Guid. Я вставив Guid как «7cee3e1c-7a2b-462d-8c3d-82dd6ae62fb4», когда оно должно было быть x'7cee3e1c7a2b462d8c3d82dd6ae62fb4'

Будем надеяться, что волосы я вытащил работать через эту проблему отрастают :)

Спасибо все для вашего ввода.

+0

Где находятся два примера? Веб сервер? Консольное приложение? Что происходит, когда вы запускаете оба примера в одном месте? – tzerb

+0

Два примера работают в простом консольном приложении, чтобы попытаться определить, что происходит. – ruskie

ответ

0

Убедитесь, что свойство BankAccountType объявлено виртуальным в BudgetEntities.

+0

Я пробовал это, но я все равно получаю ту же ошибку. Функция BudgetEntities была автоматически создана VS2010. Я не понимаю, почему он отлично работал с использованием SQL Compact DB, используя автоматически сгенерированный объект, а не для SQLite. Есть ли у вас другие предложения? – ruskie

2

Во втором примере ваш фрагмент кода начинается с:

var accoutTypes = budget.BankAccountTypes; 

Это загружает все виды банковских счетов для вашего приложения, и вам не нужно отложенной загрузки больше (EF автоматически распознает, что эти объекты были уже загружены и фиксировать отношения с банковскими счетами).

Сначала проверьте, если ваш класс счет динамического прокси (просто проверить тип a в отладчике). Если вы не ошиблись в определении класса, и ленивая загрузка не будет работать. Затем проверьте, включена ли ленивая загрузка в вашем экземпляре контекста (budget.ContextOptions.LazyLoadingEnabled).

+0

Я попытался добавить фрагмент кода в ваш пост в первый пример, и я все еще получаю исключение. Я также проверил класс учетной записи, и это не динамический прокси, хотя ContextOptions.ProxyCreationEnabled установлен в true и ContextOptiions.LazyLoadingEnabled также включен. – ruskie

+0

Я провел некоторое дополнительное тестирование и сравнил .edmx и .designer.cs, созданных для SQL Compact DB и SQLite DB, и, по сути, они идентичны, но SQLite, похоже, не загружает ссылочные объекты. Я начинаю думать, что это ограничение SQLite. Считаете ли вы, что это может быть так? – ruskie

+0

Проблемы с SQLite могут возникнуть, если вы используете своего поставщика (system.data.sqlite), потому что этот провайдер нацелен на .NET 3.5 и EFv1, поэтому некоторые функции из EFv4 не должны быть доступны. Прозрачная ленивая загрузка - это функция EFv4, но я считаю, что она не должна зависеть от поставщика, поэтому она должна работать со старым поставщиком SQLite, как ожидалось. Вы можете попытаться использовать dotConnect Devart для SQLite и проверить, не является ли проблема с поставщиком или нет. –

Смежные вопросы