Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在实体框架中删除聚合根的子对象_C#_Entity Framework_Repository_Domain Driven Design_Aggregateroot - Fatal编程技术网

C# 在实体框架中删除聚合根的子对象

C# 在实体框架中删除聚合根的子对象,c#,entity-framework,repository,domain-driven-design,aggregateroot,C#,Entity Framework,Repository,Domain Driven Design,Aggregateroot,以前可能会问这个问题,但我似乎无法在网站上找到解决方案,因此我们开始: 这是我的域模型的一个过于简化的版本。我有两个类,代表数据库中的两个表: public Class Person { public int Id { get; set;} public string Name { get; set;} public virtual List<Contact> Contacts { get; set;} public void AddContact(

以前可能会问这个问题,但我似乎无法在网站上找到解决方案,因此我们开始:

这是我的域模型的一个过于简化的版本。我有两个类,代表数据库中的两个表:

public Class Person
{
    public int Id { get; set;}
    public string Name { get; set;}
    public virtual List<Contact> Contacts { get; set;}

    public void AddContact(string value) 
    {
        //some validation code
        Contacts.Add(new Contact(value));
    }

    public void DeleteContact(Contact contact) 
    {
        //some validation code
        Contacts.Remove(contact);
    }
}

public Class Contact
{
    public int Id { get; set;}
    public string Value { get; set;}
    public virtual Person Person { get; set;}
    public int PersonId { get; set;}
}
公共类人物
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共虚拟列表联系人{get;set;}
public void AddContact(字符串值)
{
//一些验证代码
联系人。添加(新联系人(值));
}
公共联系人(联系人)
{
//一些验证代码
触点。移除(触点);
}
}
公共类联系人
{
公共int Id{get;set;}
公共字符串值{get;set;}
公共虚拟人{get;set;}
公共int PersonId{get;set;}
}
现在Person是我这里的聚合根。我试图遵循DDD原则,只为聚合根创建存储库。添加联系人效果很好

我遇到的问题是在删除联系人时。它给出了错误:

操作失败:无法更改关系,因为一个或多个外键属性不可为null。对关系进行更改时,相关外键属性设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象

有没有过去的事。如果关系属性不可为null,实体框架不应自动删除联系人

现在我知道从集合中删除与从上下文中删除不同,但我不想从域模型中引用DbContext

我只有一个人


请提供解决方案或帮助我了解我是否理解了任何错误的概念。

看起来您遇到了与中相同的问题。基本上,当您从集合中删除联系人时,实际上并不是在删除它;您只是孤立了它,在此过程中,将其PersonId设置为
null
(当然,对于
int
,这是不可能的)

一种可能的解决方案是使PersonId在Contact类中为null:

public int? PersonId { get; set; }
然后,在数据库上下文中,重写
SaveChanges
以自动删除孤立记录:

public override int SaveChanges()
{
    foreach (Contact contact in Contacts.Local.Where(c => c.PersonId == null))
    {
        Contacts.Remove(contact);
    }
    return base.SaveChanges();
}

免责声明:我尚未测试该代码,但希望这是一个良好的起点。

这是使用EF进行DDD时的常见问题。到目前为止,有两种解决方案对我很有效:

  • DeleteContact
    方法返回已删除的实例。该方法很可能是从保存存储库的应用程序服务调用的。然后可以使用它从DbContext中删除实例

  • 如果使用,您可以使用一个通知其他人有关删除联系人的信息。然后,可以在基础结构层中放置此事件的处理程序,该处理程序将从DbContext中删除联系人


  • 没用。WillCascadeOnDelete()在删除聚合根时起作用,但在本例中不起作用。我只想删除一个孩子当然,傻我。我已经更新了我的答案;希望这更相关一些。对于域模型和EF模型使用相同的类不是一个好主意。EF模型应该只提供一种为域模型提供服务的方法。@JotaBe我们如何才能做到这一点?