5

我有一个多对多的关系:如何在多对多的关系中删除?

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

说我有

Shopping Category 
Food Category 

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

现在我删除Shopping Category。我想从Shopping Category中删除Product A参考,并且我想要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

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

(*)不是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的东西...不是好的解决方案,但解决方案。

0

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

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

+0

我不明白。我以为saveUpdate会很好地重新保存它,我不确定从集合中删除实体是什么意思。我可以将1000个需要引用的产品删除,因此这似乎是我自己必须要做的级联。 – chobo2 2012-03-15 22:15:47

+0

我可能误解了你的问题,但我可以肯定地明白为什么'DeleteOrphan'和'AllDeleteOrphan'在这个实例中删除产品A. 'SaveUpdate'只会删除关联(多对多表项...'product_category'),但不会删除'产品A'。这是您在使用此级联设置时必须手动处理的内容。我不认为有一个级联来处理这个问题(尽管可能是错误的)。 – 2012-03-15 22:36:41

+0

嗯,我将不得不尝试,但我认为DeleteOrphan正是为了这种情况。我不认为这对我来说产品A不是孤儿,因为它与某物仍然有关系。 – chobo2 2012-03-15 23:27:26

相关问题