У меня есть many-many отношения между двумя таблицами, скажем, Друзья и Продукты. Если другу нравится еда, я засовываю строку в таблицу FriendsFoods, как это:
ID Friend Food
1 'Tom' 'Pizza'
FriendsFoods имеет Первичный ключ 'идентификатор' и два непустых внешних ключа 'Друг' и 'Еда' к таблицам 'Friends' и 'Foods', соответственно.
Теперь предположите, что у меня есть a Friend tom
Соответствию объекта.NET 'Tom' и Tom больше не нравится пицца (что не так с ним?)
FriendsFoods ff = tom.FriendsFoods.Where(x => x.Food.Name == 'Pizza').Single();
tom.FriendsFoods.Remove(ff);
pizza.FriendsFoods.Remove(ff);
Если я пытаюсь SubmitChanges()
на DataContext я получаю исключение, потому что он пытается вставить пустой указатель в Friend
и Food
столбцы в FriendsFoods
таблица.
Я уверен, что могу соединить некоторую замысловатую логику для отслеживания изменений в FriendsFoods
таблица, прерывание SubmitChanges()
вызовы, и т.д. чтобы попытаться заставить это прокладывать себе путь я хочу, но есть ли хороший, очевидный способ для удаления отношений Many-Many с LINQ-SQL?
Предполагая, что в самой базе данных есть правила CASCADE DELETE
, определенные для внешних ключей (в противном случае у вас возникнут проблемы), вам необходимо установить Правило удаления для каждой связи в конструкторе Linq to SQL (или DeleteRule
в AssociationAttribute
) к CASCADE
.
Вам также не нужно удалять обе стороны ассоциации - достаточно одной, либо из tom
, либо из pizza
.
Добавление: @Crispy также верно в том смысле, что интересующий вас атрибут real - это атрибут DeleteOnNull
в дочерней ассоциации. Однако , причина того, что вы не можете увидеть это в конструкторе, заключается в том, что конструктор автоматически определяет значение этого свойства на основе (a) параметра CASCADE
родительского связь с дочерним элементом и (б) является ли поле внешнего ключа допускающим значение NULL.Если у вас есть FK, не допускающий значения NULL, с CASCADE DELETE
в конструкторе Linq to SQL, он должен автоматически установить DeleteOnNull = true
для связи между дочерними и родительскими элементами, а затем удалить запись из таблицы сопоставления вместо попытки установить для нее значение NULL
.
Если вы пытаетесь удалить запись из таблицы «многие ко многим» ( FriendFoods
), удалив ее из дочерней коллекции объекта linq, вам необходимо установить Атрибут DeleteOnNull
для отношения, равного true, в файле dbml. К сожалению, вы не можете сделать это через дизайнер dbml. Вам необходимо открыть файл .dbml как файл xml, а затем вручную отредактировать xml ассоциации.
КАСКАДНОЕ УДАЛЕНИЕ здесь не применяется. Оно будет применяться только в случае удаления объекта, будь то объект Friend или Food объект, но не если вы просто хотите удалить связь. Есть ли причина, по которой вы не обращаетесь к реляционной таблице напрямую? Я думаю, это было бы гораздо более чистым решением.