在实体框架中使用pocos的关系问题

本文关键字:pocos 关系 问题 实体 框架 | 更新日期: 2023-09-27 18:16:19

我有一个使用POCO类的应用程序,当我试图设置新对象和持久对象之间的关系时,我得到了一个错误。

我有这些类:SecurityUserSecurityGroupSecurityUser有一个属性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时,情况就不一样了。

在实体框架中使用pocos的关系问题

这是那些丑陋的关系修复问题之一,经常给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操作符创建组时,代码也可以工作。