1

Использование Entity Framework 6 у меня есть основные и детализированные сущности. У меня есть WinForm, который отображает подробные данные в сетке для данного основного объекта. Контекст проводится на протяжении всей жизни формы.Удаление как локальных дочерних объектов, так и дочерних объектов DB в EF6

Список деталей привязываются к сетке с BindingList:

detailBindingSource = new BindingSource(); 
detailBindingList = new BindingList<Detail>(master.Details); 
detailBindingSource.DataSource = detailBindingList; 
detailGrid.SetDataBinding(detailBindingSource, ""); 

Когда пользователь удаляет строку в таблице, следующий код удаляет деталь (комментарии быть моей интерпретацией того, что я думаю делает код):

var row = detailGrid.GetRow();   // Get the currently selected row in the detail grid 
var detail = (Detail)row.DataRow;  // Get the entity related to the row 
row.Delete();       // This will delete the line from the list, but not from the DB 
if (detail.ID > 0)      // Don't try to delete a row that's only been added in memory and not to the DB 
    dbset.Remove(detail);    // This will mark the entity to be deleted from the DB 

И когда пользователь заканчивает изменения сохраняются:

context.SaveChanges(); 

Все работает хорошо, если я удаляю существующие строки и сохраняю. Все работает хорошо, если я удаляю строки, которые были добавлены в течение жизни формы/контекста и сохраняются. Но если я как - удалить существующую строку и удалить вновь добавленный и-еще-не-сохраненную строку - я получаю следующее исключение по экономии:

System.InvalidOperationException: Операция не удалась: Связь не может быть изменена, поскольку одно или несколько свойств внешнего ключа не могут быть обнулены. Когда происходит изменение отношения, соответствующее свойство внешнего ключа устанавливается равным нулевому значению. Если внешний ключ не поддерживает нулевые значения, необходимо определить новое отношение, для свойства внешнего ключа должно быть назначено другое ненулевое значение, или не связанный с ним объект должен быть удален.

Поиск информации об исключении, я нашел несколько ссылок на то, как удаление из списка навигации родительского объекта недостаточно для удаления самого объекта, но я думал, что вызов Remove в коде выше (и кажется, что я удаляю только существующие строки).

Кто-нибудь знает, почему это происходит только при удалении строк каждого типа (нового и старого), в котором возникает исключение?

+0

Я думаю, вы получили эту ошибку, потому что пытаетесь удалить новую запись, которая НЕ ЕСТЬ идентификатор, потому что контекст не сохраняется. Таким образом, вы добавляете запись и пытаетесь удалить из объекта somethig, которые существуют только в DataGridView. – CristiC777

+0

Я сохраняю новую строку в поле «Оставить событие» из строки, и если вы хотите нажать «Удалить», вы можете сделать это :) и будет удален, потому что уже сохранен в контексте;) – CristiC777

ответ

0

Это не ответ, почему происходит ошибка (или, возможно, почему это не происходит в некоторых случаях), но решение отделить вновь добавленные строки, которые отсутствуют в базе данных:

if (detail.ID > 0) 
    dbset.Remove(detail); 
else 
    dbset.Detach(detail); 
0

Есть ли существующая строка, которую вы удаляете на всех трех тестах? Я имею в виду, это одна и та же строка с теми же базовыми данными, такими же отношениями? Кажется, что в третьем тесте существующая строка, которую вы удаляете, имеет отношение к другой таблице, которая сама имеет отношение, отличное от нуля, к третьей таблице. Когда отношение исчезает, соответствующая строка (и) на третьей таблице также должна быть удалена.

+0

Спасибо за ваше предложение, но они одинаковы строки, а дочерние строки не связаны ни с чем, кроме родительской строки. – Giles

+0

Создаете ли вы дочерние строки при создании родительских строк?Если это так, попробуйте явно удалить связанные дочерние строки при удалении родителя. –

0

Если вы создали и удалили контекст, как и вам, у вас не будет проблем. Не используйте глобальные контексты.

Смежные вопросы