В целом неправильно, что вы можете « удалить элемент из базы данных » обоими методами. Если быть точным, это так:
ObjectContext.DeleteObject(entity)
помечает объект какDeleted
в контексте. (Это EntityState
будет Deleted
после этого.) Если вы позвоните SaveChanges
позже, EF отправит DELETE
инструкцию SQL в базу данных. Если никакие ссылочные ограничения в базе данных не нарушаются, объект будет удален, в противном случае выдается исключение.
EntityCollection.Remove(childEntity)
отмечает отношения между родителем и childEntity
asDeleted
. Если childEntity
сам удаляется из базы данных, и что именно происходит при вызове, SaveChanges
зависит от типа отношений между ними:
Если связь является необязательной , т. Е. Внешний ключ, который ссылается от дочернего к родительскому в базе данных, допускает NULL
значения, этот внешний будет установлен в нуль, и если вы вызовете SaveChanges
это NULL
значение для, childEntity
будет записано в базу данных (то есть отношение между два удаляются). Это происходит с оператором SQL UPDATE
. Никакого DELETE
заявления не происходит.
Если связь требуется (FK не допускает NULL
значений) и связь не идентифицируется (что означает, что внешний ключ не является частью дочернего (составного) первичного ключа), вам необходимо либо добавить дочерний элемент к другому родительскому элементу, либо вы должны явно удалить ребенка (с помощью DeleteObject
then). Если вы не сделаете ничего из этого, ссылочное ограничение будет нарушено, и EF выдаст исключение при вызове SaveChanges
- печально известное исключение « Связь не может быть изменена, потому что одно или несколько свойств внешнего ключа не допускают значения NULL » или аналогичный.
Если отношения идентификации (это обязательно требуется , то потому , что какая - либо часть первичного ключа не может быть NULL
) EF будет отмечать , childEntity
как Deleted
и. При вызове SaveChanges
SQL- запрос DELETE
будет отправлен в базу данных. Если никакие другие ссылочные ограничения в базе данных не нарушаются, сущность будет удалена, в противном случае выдается исключение.
На самом деле я немного смущен разделом «Примечания» на странице MSDN, которую вы связали, потому что в нем говорится: « Если отношение имеет ограничение ссылочной целостности, вызов метода Remove для зависимого объекта помечает и отношение, и зависимый объект для удаления. ". Мне это кажется неточным или даже неправильным, потому что все три приведенных выше случая имеют « ограничение ссылочной целостности », но только в последнем случае фактически удален дочерний элемент. (Если только они не означают под « зависимым объектом » объект, который участвует в идентифицирующих отношениях, что, однако, было бы необычной терминологией.)
NULL
как «Не значение» (вместо «значениеNULL
», как я писал иногда немного небрежно), то «необязательное отношение» не противоречит этому определению ссылочной целостности.ObjectContext.DeleteObject
?Если вы действительно хотите использовать Deleted, вам придется сделать свои внешние ключи обнуляемыми, но тогда вы получите потерянные записи (что является одной из основных причин, по которой вы не должны этого делать в первую очередь). Так что просто используйте
Remove()
ObjectContext.DeleteObject (entity) отмечает объект как удаленный в контексте. (После этого EntityState удаляется.) Если после этого вы вызываете SaveChanges, EF отправляет SQL-запрос DELETE в базу данных. Если никакие ссылочные ограничения в базе данных не нарушаются, объект будет удален, в противном случае выдается исключение.
EntityCollection.Remove (childEntity) помечает связь между parent и childEntity как удаленную. Если сам childEntity удален из базы данных, и что именно происходит при вызове SaveChanges, зависит от типа отношений между ними:
Стоит отметить, что настройка
.State = EntityState.Deleted
не вызывает автоматически обнаруживаемых изменений. ( архив )источник