Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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#_Design Patterns_Sql Server 2008_Recursion - Fatal编程技术网

C# 如何实现递归删除?

C# 如何实现递归删除?,c#,design-patterns,sql-server-2008,recursion,C#,Design Patterns,Sql Server 2008,Recursion,我有以下情况: 客户包含项目,项目包含许可证。 很好,因为存档,我们不会删除任何内容,而是使用IsDeleted。 否则我可以使用级联删除 Owkay我使用存储库模式,所以我调用 customerRepository.Delete(customer); 但问题开始了。客户设置为isdeleted true。但是我想删除该客户的所有项目,每个被删除的项目也应该删除所有许可证 我想知道是否有适当的解决办法。 但它必须表现得很好 请注意,这是实际问题的一个简单版本。一个客户也有链接到许可证的站点,但

我有以下情况:

客户包含项目,项目包含许可证。 很好,因为存档,我们不会删除任何内容,而是使用IsDeleted。 否则我可以使用级联删除

Owkay我使用存储库模式,所以我调用

customerRepository.Delete(customer);
但问题开始了。客户设置为isdeleted true。但是我想删除该客户的所有项目,每个被删除的项目也应该删除所有许可证

我想知道是否有适当的解决办法。 但它必须表现得很好

请注意,这是实际问题的一个简单版本。一个客户也有链接到许可证的站点,但我只是想为你们简化这个问题

我在一个C#环境中工作,使用sql server 2008作为数据库


编辑:我正在使用Enterprise库连接到数据库

一个选项是使用触发器在数据库中执行此操作。我想另一个选择是使用级联更新,但这可能不适合您的域的工作方式


就个人而言,我可能会咬紧牙关,编写C代码来为我设置IsDeleted type字段(如果只有一个应用程序访问数据库)。

这完全取决于你的DAL。例如,可以设置NHibernate映射以级联删除所有这些关联对象,而无需额外代码。我相信EF也有类似的东西。您如何连接到数据库


如果您的对象没有被持久化,那么一旦没有对它们的引用,.NET GC将清除所有项目对象。从您的问题中,我假定您正在谈论从数据库中删除它们?

我建议只编写一个存储过程(或一组存储过程)来封装此逻辑,它看起来像这样:

update Customer set isDeleted = 1
where  CustomerId = @CustomerId

/* Say the Address table has a foreign key to customer */
update Address set isDeleted = 1
where  CustomerId = @CustomerId

/* 
   To delete related records that also have child data,
   write and call other procedures to handle the details 
*/
exec DeleteProjectByCustomer(@CustomerId)

/* ... etc ... */
private bool _IsDeleted;
public bool IsDeleted
{
   get
   {
      return _IsDeleted || (Parent == null ) ? false : Parent.IsDeleted;
   }
   set
   {
      _IsDeleted = value;
   }
}

然后从
customerRepository调用此过程。在事务中删除

如果您的关系是固定的(即许可证始终与项目相关,项目始终与客户相关),则您可以不级联更新。由于您已经在处理查询中的软删除问题,您还可以添加检查层次结构的痛苦:

SELECT [...] FROM License l
JOIN Project p ON l.ProjectID = p.ID
JOIN Customer c on p.CustomerID = c.ID
WHERE l.IsDeleted <> 1 AND p.IsDeleted <> 1 AND c.IsDeleted <> 1

…尽管您必须小心地在数据库中实际存储private
\u IsDeleted
值,而不是
IsDeleted
的值是的,我认为触发器是危险的。你会找不到他们的,是的。人们有时会“忘记”触发器也被创建了。就个人而言,我喜欢触发器的想法,因为它可以确保在记录被设置为删除时,会发生适当的其他更改。我认为通过应用程序代码这样做是不负责任的。它存在数据完整性问题的风险。如果有人被意外删除,触发器也可以设置为在所有子记录中取消删除。@HLGEM-我认为触发器是一个可行的解决方案,特别是当您有多个应用程序访问数据库时。是的,这是为一个级别的提取而做的,但是如果您降低了2-3个级别,则只加载一个项目会使查询变得更仔细