如何删除多对多的关系?

时间:2012-03-15 17:28:16

标签: nhibernate fluent-nhibernate many-to-many cascading-deletes nhibernate-cascade

我有很多关系:

  

产品有很多类别,类别有很多产品。

说我有

Shopping Category  
Food Category

Product A - Shopping Category, Food Category  
Product B - Shopping Category

现在我删除了Shopping Category。我希望Product A引用从Shopping Category中删除,我希望Product B完全删除。

我最终会:

Product A - Food Category.

如何在nhibernate中执行此操作(我使用流利的nhibernate)。

我尝试使用级联DeleteOrphanAllDeleteOrphan,但当我这样做并删除购物时,产品A和B都会被删除。

public class CategoryMapping : ClassMap<Category>
{
    public CategoryMapping()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();

        Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize();
        HasManyToMany(x => x.Products).Cascade.DeleteOrphan();
    }
}


public class ProductMapping : ClassMap<Product>
{
    public ProductMapping()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize();
        HasManyToMany(x => x.Categories);
    }
}

  unitOfWork.BeginTransaction();
  Category category =session.Load<Category>(id);
  session.Delete(category);
  unitOfWork.Commit();

2 个答案:

答案 0 :(得分:2)

我认为这不能通过映射现有数据结构来处理。我认为您需要编写一些手动代码(*)或更改数据结构。

(*)不是100%确定它有效......

unitOfWork.BeginTransaction();
Category category =session.Load<Category>(id);
var productsDel = category.Products.Where(p => p.Categories.Count == 1);
productsDel.ForEach(p => session.Delete(p));
session.Delete(category);
unitOfWork.Commit();

其他:

我也在考虑为你的交叉引用表添加映射。然后,您应该能够配置映射,以便它只删除该交叉引用表中的记录。您需要验证是否有没有引用的产品并定期删除它们。 (一些定期清理代码,比如运行一些存储过程)。我知道这个解决方案闻起来很糟糕:)仍有触发器和其他SQL Server的东西...不管怎样都不是好的解决方案,而是解决方案。

答案 1 :(得分:0)

如果您只想删除两者之间的关联,请使用Cascade.SaveUpdate()

然后只是从集合中删除实体并提交事务如果你正在使用事务,如果不是你将需要做Session.Flush