在实体框架中使用pocos的关系问题
本文关键字:pocos 关系 问题 实体 框架 | 更新日期: 2023-09-27 18:16:19
我有一个使用POCO类的应用程序,当我试图设置新对象和持久对象之间的关系时,我得到了一个错误。
我有这些类:SecurityUser
和SecurityGroup
。SecurityUser
有一个属性Group_ID
,我可以设置用户组的ID,还有一个属性SecurityGroup
,我可以设置对象本身。当我尝试为这个属性设置一个新的SecurityGroup
时,我得到了POCO类上的"空引用"异常。下面是我的代码示例:
using (SecurityEntities context = new SexurityEntities(connectionString))
{
SecurityUser user = context.SecurityUsers.SingleOrDefault(cond => cond.User_ID == 1);
SecurityGroup group = new SecurityGroup();
user.SecurityGroup = group;
context.SecurityGroups.AddObject(group);
context.SaveChanges();
}
当我这样做而不使用没有POCO类的实体框架时,一切都很顺利,但使用POCO时,情况就不一样了。
这是那些丑陋的关系修复问题之一,经常给EF 4 poco带来麻烦。
如果你看一下由POCO生成器创建的类,你会看到一个名为"Association Fixup"的区域,其中包含一些方法,如FixupSecurityGroup
或类似的从POCO的属性设置器调用的方法。我可以重现你的问题,但即使在调试之后,我也找不到在这些修复方法中出错的确切点。所以,我无法解释为什么你的代码不能工作。
但我找到了两个可行的解决方案:
1)不使用new
创建组,而是使用CreateObject
方法:
SecurityUser user = context.SecurityUsers
.SingleOrDefault(cond => cond.User_ID == 1);
SecurityGroup group = context.SecurityGroups.CreateObject();
user.SecurityGroup = group;
context.SaveChanges();
(我已经删除了AddObject
。这不是必要的,因为EF识别出该组是新的,并创建了一个INSERT语句,但是单独删除AddObject
并不能解决问题。
你的POCO属性是virtual
, EF将为SecurityUser
创建一个动态代理,当你从DB加载它时。显然,出于某种原因,您创建的SecurityGroup
也需要动态代理,否则我们会得到空引用异常。CreateObject
将创建这个代理。
2)或者你可以关闭代理创建:
context.ContextOptions.ProxyCreationEnabled = false;
SecurityUser user = context.SecurityUsers
.SingleOrDefault(cond => cond.User_ID == 1);
SecurityGroup group = new SecurityGroup();
user.SecurityGroup = group;
context.SaveChanges();
现在,user
不是动态代理,当您使用普通的new
操作符创建组时,代码也可以工作。