实体框架,SQLite和Lazy加载 [英] Entity Framework, SQLite and Lazy loading

查看:219
本文介绍了实体框架,SQLite和Lazy加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个使用SQL Compact和EF4的C#预算应用程序,我通过VS2010实体数据模型模板创建了EF模型。这一切都很好。然而,我正在考虑开发一个iPhone应用程序来支持现金交易,并认为在两个平台上都支持后端DB最好。在创建SQLite数据库并创建新模型之后,当我尝试通过我的模型中的导航属性访问引用的数据时,遇到了一个问题。当尝试显示引用表的属性时,我得到一个NullReferenceException。



当使用以下代码时,我在最后一行得到异常:

  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); //这里发生异常。
}

奇怪的是,在这个例子中不会出现异常。我不知道发生了什么事情? 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))。
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); //异常不会发生。
}

这只是一个简单的例子,我知道我可以通过添加来修复它。 Include(BankAccountTypes)到查询,但是我有其他查询是非常复杂的,创建对象,包括查询中的引用对象的属性,我不太清楚如何解决这个问题。 >

编辑:
在项目休息之后,我回到了这个问题,我终于解决了我的问题。它与代码无关。这是与数据。我已经通过转储和加载将SQL Compact数据库转换为SQLite,并且我的Guid列数据的语法错误。我应该将Guid作为'7cee3e1c-7a2b-462d-8c3d-82dd6ae62fb4',当它应该是x'7cee3e1c7a2b462d8c3d82dd6ae62fb4'



希望我拉出来的头发通过这个

解决方案



p>在第二个例子中,您的代码段以...开头:

  var accoutTypes = budget.BankAccountTypes; 

将所有银行帐户类型加载到您的应用程序,您不需要延迟加载(EF将自动识别这些实体已经加载并修复与银行帐户的关系)。



首先检查您的帐户类是否是动态代理(只需检查类型 a调试器中的)。如果不是你在类定义中犯了一些错误,懒惰加载将不起作用。接下来检查是否在上下文实例上启用延迟加载( budget.ContextOptions.LazyLoadingEnabled 属性)。


Hi I had developed a C# Budget application using SQL Compact and EF4, I created the EF model through the VS2010 Entity Data Model template. It is all working very well. However I am considering developing a iPhone app to support cash transactions and thought it would be better to have the back end DB supported on both platforms. After creating the SQLite DB and creating a new model I have come across a problem when trying to access referenced data via the Navigation properties in my model. I am getting a NullReferenceException when trying to display a property of a referenced table.

When using the following code I get the exception on the last line:

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.
}

Strange thing is that the exception doesn't occur in this example. I'm not sure what is going on?

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.
}

This is only a simple example and I know I could fix it by adding .Include("BankAccountTypes") to the query however I have other queries that are quite complex that are creating object which include properties from referenced object with in the query and I am not quite sure how to get around this issue for them.

EDIT: After having a break between projects I have come back to this problem and I have finally resolved my problem. it had nothing to do with the code. It was with the data. I had converted a SQL Compact database to SQLite via a dump and load and had the syntax wrong for my Guid column data. I was inserting the Guid as '7cee3e1c-7a2b-462d-8c3d-82dd6ae62fb4' when it should have been x'7cee3e1c7a2b462d8c3d82dd6ae62fb4'

Hopefully the hair I pulled out working through this problem will grow back :)

Thanks everyone for your input.

解决方案

In second example your code snippet begins with:

var accoutTypes = budget.BankAccountTypes;

This loads all bank account types to your application and you don't need lazy loading anymore (EF will automatically recognize that these entities were already loaded and fix relations with bank accounts).

First check if your account class is dynamic proxy (just check type of a in the debugger). If it is not you made some mistake in the class definition and lazy loading will not work. Next check if lazy loading is enabled on your context instance (budget.ContextOptions.LazyLoadingEnabled property).

这篇关于实体框架,SQLite和Lazy加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆