Как удалить отношения "многие ко многим"?
У меня есть отношения многие ко многим:
Продукт имеет много категорий, а категория имеет много продуктов.
Скажи у меня
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).
Я пытался использовать Cascade DeleteOrphan
а также AllDeleteOrphan
но когда я делаю это и удаляю покупки, продукт 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... не все равно хорошие решения, но есть решения.
Если вы просто хотите удалить связь между двумя использования Cascade.SaveUpdate()
Затем просто удалите сущность из коллекции и зафиксируйте транзакцию, если вы используете транзакции, если нет, вам нужно будет выполнить Session.Flush