C# 打破POCO关系
我在破坏两个实体之间的关系时遇到问题。假设我们有一个C# 打破POCO关系,c#,asp.net-mvc,entity-framework,poco,C#,Asp.net Mvc,Entity Framework,Poco,我在破坏两个实体之间的关系时遇到问题。假设我们有一个子实体属于一个父实体,一个父实体有许多子实体。现在,在我的前端,用户可以选择一个单选按钮来选择父项子项属于哪个或选择“无”。我遇到的问题是,当我编辑一个子记录并选择“无”时,它似乎并没有破坏现有的关系 在我的业务逻辑中,我正在执行以下操作: child.Parent = parentRepository.Find(command.ParentID); 如果没有记录与传入的ID匹配,则repository方法返回null,并且当我调试并跨过这一
子实体
属于一个父实体
,一个父实体
有许多子实体。现在,在我的前端,用户可以选择一个单选按钮来选择父项
子项
属于哪个或选择“无”。我遇到的问题是,当我编辑一个子记录并选择“无”时,它似乎并没有破坏现有的关系
在我的业务逻辑中,我正在执行以下操作:
child.Parent = parentRepository.Find(command.ParentID);
如果没有记录与传入的ID匹配,则repository方法返回null,并且当我调试并跨过这一行时,选择“None”会给出一个ID 0,Child.Parent仍然有一个对先前选择的父实体的引用。事实上,即使显式设置Child.Parent=null;似乎并没有破坏这种联系
更让我困惑的是,这不是一种始终如一的行为。有时,相同的代码会破坏关系并将Child.Parent设置为null!有人能给我指一下正确的方向吗
更新
我更新了代码以确保回购协议返回null
Parent parent = parentRepository.Find(command.ParentID);
if (parent == null)
child.parent = null;
else
child.parent = parent;
调试显示行child.parent=null代码>正在执行,但当我在这一行之后检查child.parent
时,它仍然显示对先前引用的parent
对象的引用。但有时,它会正确地设置为null。此版本适用于:
Parent parent = parentRepository.Find(command.ParentID);
if (parent == null)
{
child.parent = null;
child.parent = null;
}
else
child.parent = parent;
为什么我必须将其设置为null两次才能获得一致的行为?我是否必须以某种方式明确声明子
实体上的父项
可为空?是的,您确实需要声明父项可为空
如果在子级上公开外键属性,则该属性必须为空。因此,如果您的孩子具有ParentId属性,则应如下所示:
public int? ParentId { get; set; }
public virtual Parent { get; set; }
modelBuilder.Entity<Child>.HasOptional(d => d.Parent).WithMany(p => p.Children);
context.Children.Include(c => c.Parent).Find(id);
如果您使用的是fluent API,您可以告诉EF父级可以为空,如下所示:
public int? ParentId { get; set; }
public virtual Parent { get; set; }
modelBuilder.Entity<Child>.HasOptional(d => d.Parent).WithMany(p => p.Children);
context.Children.Include(c => c.Parent).Find(id);
这是您可以实际使用的代码,以确保私有字段设置为null
评论回复
听起来确实存在延迟加载的问题。试试这个
在存储库Find方法中,加载父对象。您可以通过以下方式实现:
public int? ParentId { get; set; }
public virtual Parent { get; set; }
modelBuilder.Entity<Child>.HasOptional(d => d.Parent).WithMany(p => p.Children);
context.Children.Include(c => c.Parent).Find(id);
这将使child.Parent已经加载到上下文中,设置为null一次就足够了 也粘贴在子模型代码中。如果您在OnModelCreating事件中执行任何fluent API调用,那么也显示它们。好的,因此我按照建议更改了Parent属性以查看发生了什么。当集合被调用时,_parent为null,它将保持null,直到我将光标移到公共虚拟父集合上!然后,我可以成功地将其设置为null。如果我不跳过它,它将保持为null,就像它没有从数据库中提取记录一样,所以当我将它设置为null时,它什么也不做。这是在进行某种惰性加载吗?我本以为当我打电话给child.parent时,EF会给父母补水?看起来我的行为很正常。由于父导航属性是虚拟的,因此将应用延迟加载。第一次调用navigation属性时,相关对象似乎从db中水合。因此,当我使用child.parent=null将其设置为null时;代码真正做的就是从数据库中获取记录。因此,为什么第二个child.parent=null;尝试有效。不管怎样,谢谢你的回答,这真的帮了我的忙。