我正在使用VS2010,EF4功能CTP(最新版本)和POCO对象,例如下面的示例:
class Person
{
public int ID { get; set; }
public string Name { get; set; }
public virtual IList<Account> Accounts { get; set; }
...
}
class Account
{
public string Number { get; set; }
public int ID { get; set; }
...
}
为简洁起见,假设下面的context
是EF4的上下文对象。我在实体类型和数据库之间有一个dbml映射,我这样使用它没有问题:
Person doug = context.Persons.CreateObject();
doug.Name = "Doug";
context.Add(doug);
context.Save();
doug.Accounts.Add(new Account() { Name = "foo" });
context.Save(); // two calls needed, yuck
此时,数据库具有名为“Doug”的Person记录和帐户记录“foo”。我可以查询并获得那些记录就好了。但是,如果我尝试在之前添加帐户,我保存了Person,则Accounts列表为null(代理尚未在该属性上创建实例)。见下一个例子:
Person doug = context.Persons.CreateObject();
doug.Name = "Doug";
doug.Accounts.Add(new Account() { Name = "foo" }); // throws null reference exception
context.Add(doug);
context.Save();
还有其他人遇到过这个吗?更好的是,有没有人找到一个好的解决方案?
答案 0 :(得分:3)
Person doug = context.Persons.CreateObject();
doug.Name = "Doug";
context.Add(doug);
doug.Accounts.Add(new Account() { Name = "foo" });
context.Save();
这将有效
答案 1 :(得分:2)
是的,是的!
当您启动POCO时(与上下文中的CreateObject相反),不会为您提供代理。这似乎是显而易见的,但在追逐类似问题时我不得不明确地提醒自己这种行为。 (我知道这不是你在问题中描述的情况,但应该承认整体问题。)
在POCO的构造函数中初始化集合不会干扰我在自己的测试中观察到的正确的EF4代理延迟加载行为。
好的,这一切都说了,我现在看到你对前一个答案的评论 - 当我从我的上下文中请求一个新的Person时,为什么我没有代理的Addresses集合?你是否在上下文中启用了延迟加载?看看我们如何处理导航属性,我可以看到关闭延迟加载的位置可能会对这种情况产生影响。
答案 2 :(得分:1)
ISTM,如果你希望框架为你做这一切,那么你真的没有“POCO”,是吗?使用上面的代码学习Person
课程。如果不涉及EF,你会期望Accounts
属性在构造之后的状态,没有构造函数?在我看来,CLR将保证它们为空。
是的,代理可以在必要时初始化此值以实现DB值,但在EF中,“POCO”实际上意味着“ Plain ”。不是“运行时生成的代码,我们假装是'普通'”。