Entidade Framework .Remove () vs. .DeleteObject ()

Você pode remover um item de um database usando o EF usando os dois methods a seguir.

O primeiro é o EntityCollection e o segundo no ObjectContext .

Quando cada um deve ser usado?

É um preferido sobre o outro?

Remove() retorna um bool e DeleteObject() retorna void .

Não é geralmente correto que você pode ” remover um item de um database ” com os dois methods. Para ser preciso, é assim:

  • ObjectContext.DeleteObject(entity) marca a entidade como Deleted no contexto. (É EntityState é Deleted depois disso.) Se você chamar SaveChanges depois, a EF enviará uma instrução SQL DELETE para o database. Se nenhuma restrição referencial no database for violada, a entidade será excluída, caso contrário, uma exceção será lançada.

  • EntityCollection.Remove(childEntity) marca o relacionamento entre pai e childEntity como Deleted . Se a childEntity si for excluída do database e o que exatamente acontece quando você chama SaveChanges depende do tipo de relação entre os dois:

    • Se o relacionamento for opcional , isto é, a chave estrangeira que se refere do filho ao pai no database permitir valores NULL , esse estrangeiro será definido como nulo e, se você chamar SaveChanges esse valor NULL para childEntity será gravado no database ( ou seja, a relação entre os dois é removida). Isso acontece com uma UPDATE SQL UPDATE . Nenhuma instrução DELETE ocorre.

    • Se o relacionamento for necessário (o FK não permite valores NULL ) e o relacionamento não estiver identificando (o que significa que a chave estrangeira não faz parte da chave primária (composta) do filho), você deve adicionar o filho a outro pai ou você tem que excluir explicitamente o filho (com DeleteObject seguida). Se você não fizer nada disso, uma restrição referencial será violada e a EF lançará uma exceção quando você chamar SaveChanges – a infame ” A relação não pôde ser alterada porque uma ou mais propriedades da chave estrangeira não é anulável “ ou similar.

    • Se a relação estiver se identificando (é necessariamente necessária , pois qualquer parte da chave primária não pode ser NULL ), a EF também marcará a childEntity como Deleted . Se você chamar SaveChanges uma instrução SQL DELETE será enviada ao database. Se nenhuma outra restrição referencial no database for violada, a entidade será excluída, caso contrário, uma exceção será lançada.

Na verdade, estou um pouco confuso sobre a seção Remarks na página do MSDN que você vinculou porque diz: ” Se o relacionamento tiver uma restrição de integridade referencial, chamar o método Remove em um object dependente marca o relacionamento eo object dependente para exclusão. “. Isso parece impreciso ou até errado para mim porque todos os três casos acima têm uma ” restrição de integridade referencial “, mas apenas no último caso a criança é de fato excluída. (A menos que eles signifiquem com ” object dependente ” um object que participa de um relacionamento de identificação que seria uma terminologia incomum embora.)

Se você realmente quer usar Deleted, você teria que tornar suas foreign keys anuláveis, mas então você terminaria com registros órfãos (que é uma das principais razões pelas quais você não deveria estar fazendo isso em primeiro lugar). Então é só usar o Remove()

ObjectContext.DeleteObject (entidade) marca a entidade como excluída no contexto. (É EntityState é excluído depois disso.) Se você chamar SaveChanges depois, a EF enviará uma instrução SQL DELETE para o database. Se nenhuma restrição referencial no database for violada, a entidade será excluída, caso contrário, uma exceção será lançada.

EntityCollection.Remove (childEntity) marca o relacionamento entre pai e childEntity como Excluído. Se a childEntity em si for excluída do database e o que exatamente acontece quando você chama SaveChanges depende do tipo de relação entre os dois:

Uma coisa digna de nota é que a configuração .State = EntityState.Deleted não ativa a mudança detectada automaticamente. ( arquivo )