Удаление отношений LINQ-to-SQL и «многие ко многим» - PullRequest
5 голосов
/ 03 апреля 2010

У меня есть отношения многие ко многим между двумя столами, скажем, Друзья и Еда. Если другу нравится еда, я добавляю строку в таблицу FriendsFoods, например:

ID Friend Food
1 'Tom' 'Pizza'

FriendsFoods имеет первичный ключ 'ID' и два ненулевых внешних ключа 'Friend' и 'Food' для таблиц 'Friends' и 'Foods' соответственно.

Теперь предположим, что у меня есть Friend tom .NET объект, соответствующий '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() и т. Д., Чтобы попытаться заставить это работать так, как я хочу, но есть ли хороший , чистый способ удалить отношение «многие ко многим» с помощью LINQ-To-SQL?

Ответы [ 3 ]

3 голосов
/ 03 апреля 2010

Если вы пытаетесь удалить запись из таблицы «многие ко многим» (FriendFoods), удалив ее из дочерней коллекции сущности linq, вам необходимо установить атрибут DeleteOnNull в отношение равно true в файле dbml. К сожалению, вы не можете сделать это через дизайнер dbml. Вы должны открыть файл .dbml как файл xml, а затем вручную отредактировать xml ассоциации.

См. Как удалить записи из дочерней коллекции в LINQ to SQL?

3 голосов
/ 03 апреля 2010

Если в самой базе данных есть правила CASCADE DELETE, определенные для внешних ключей (в противном случае у вас проблемы), вам нужно установить Правило удаления для каждого отношения в конструкторе Linq to SQL (или от DeleteRule в AssociationAttribute) до CASCADE.

Вам также не нужно удалять обе стороны ассоциации - достаточно будет либо с tom, либо с pizza.

Приложение: @ Crispy также верно в том смысле, что интересующий вас атрибут real является атрибутом DeleteOnNull в дочерней ассоциации. Однако , причина, по которой вы не можете видеть это в конструкторе, заключается в том, что дизайнер автоматически определяет значение этого свойства на основе (a) параметра CASCADE ассоциации «родитель-потомок» и (b) является ли поле внешнего ключа обнуляемым. Если у вас есть ненулевой FK с CASCADE DELETE в конструкторе Linq to SQL, он должен автоматически установить DeleteOnNull = true для связи «ребенок-родитель» и впоследствии удалить запись из таблицы сопоставления вместо попытки установить ее ассоциации с NULL.

2 голосов
/ 03 апреля 2010

УДАЛЕНИЕ КАСКАДА здесь не применяется. Это применимо только в том случае, если объект удаляется, либо объект Friend, либо объект Food, но не если вы просто хотите удалить связь. Есть ли причина, по которой вы не обращаетесь к реляционной таблице напрямую? Я думаю, что это было бы намного более чистым решением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...