2009-12-10 80 views
1

我有以下情况:如何实现递归删除?

客户包含项目和项目包含许可证。 由于存档,我们不会删除任何内容,而是使用IsDeleted。 Otherweise我可以使用级联删除。

Owkay我与存储库模式工作,所以我打电话

customerRepository.Delete(customer); 

但在这里开始的问题。客户被设置为true。但是,我想删除该客户的所有项目,每个被删除的项目也应该删除所有的许可证。

我想知道是否有适当的解决方案。 但它必须是高性能的。

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

我正在使用sql server 2008作为数据库的C#环境中工作。

编辑:我使用的是企业单位库连接到数据库

回答

1

我建议只写存储过程(或存储过程组)来封装这个逻辑,这将是这个样子:

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 ... */ 

然后再打一个事务中从customerRepository.Delete此过程。

2

一个办法是这样做与触发器数据库。我想另一种选择是使用Cascade更新,但这可能不适合您的域名的工作方式。

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

+0

是的,我认为触发是危险的。你可能会失去他们的踪迹。 – user29964 2009-12-10 09:39:48

+0

是的。人们有时会“忘记”触发器也已经创建。 – RichardOD 2009-12-10 10:47:10

+0

就我个人而言,我喜欢这个触发器的想法,因为它可以确保每次将记录设置为删除时,都会发生适当的其他更改。我认为通过应用程序代码来做这件事是不负责任的。它有风险有数据完整性问题。如果有人被意外删除,触发器也可以设置为通过所有子记录取消删除。 – HLGEM 2009-12-10 15:52:19

0

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

如果你的对象没有被保存,那么.NET GC将会在你没有引用它们的时候将所有的项目对象清除。我从你的问题推测,你正在谈论的是从数据库中删除它们?

0

如果您的关系是固定的(即许可证总是与项目相关,并且项目与客户有关),那么您可以不用级联更新。既然你已经与软删除的查询中的疼痛处理,你不妨加入检查层次的痛:

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 bool _IsDeleted; 
public bool IsDeleted 
{ 
    get 
    { 
     return _IsDeleted || (Parent == null) ? false : Parent.IsDeleted; 
    } 
    set 
    { 
     _IsDeleted = value; 
    } 
} 

...虽然你一定要小心实际存储在数据库中的私人_IsDeleted值和IsDeleted不是值。

+0

是啊,这已经完成了一个级别的提取,但如果你是2-3级别的查询得到很多thougher只加载一个项目 – user29964 2009-12-10 20:12:36