Entity Framework Cascade Удаление, даже если CASCADE не настроен в базе данных

У меня есть отношение внешнего ключа между двумя таблицами UserProducts и Users в моей базе данных, причем UserProducts имеет UserID, ссылающийся на UserID в таблице Users.

ALTER TABLE [dbo].[UserProducts]  WITH CHECK ADD  CONSTRAINT [FK_UserProducts_Users] FOREIGN KEY ([UserID])
REFERENCES [dbo].[Users] ([UserID])
GO

ALTER TABLE [dbo].[UserProducts] CHECK CONSTRAINT [FK_UserProducts_Users]
GO

Столбец UserID в таблице UserProducts является частью составного первичного ключа с другим столбцом ProductID. Также есть два дополнительных столбца DateTime, поэтому Entity Framework не рассматривает UserProducts как таблицу ссылок.

В этом внешнем ключе НЕТ каскадного удаления, и я не настроил ничего для обработки OnDelete в ассоциации внешнего ключа Entity Framework. Тем не менее, когда я удаляю объект User из кода, Entity Framework позволяет удалить UserProducts, связанные с ним по UserID. Для этого также генерируется много SQL: для каждой связанной записи в таблице UserProducts существует отдельная команда DELETE.

Код для выполнения удаления объекта выглядит следующим образом:

using (var context = new LicensingRegistrationContext(_csb))
{
    context.Database.Log = a => _logger.Trace(a);

    var dbUser = GetUserDbSetWithIncludes(context)
        .Where(a => a.UserID == user.Id).Single();

    context.DbUsers.Remove(dbUser);

    //TODO(MRL): Um...how are the dbUserProducts being removed???

    context.SaveChanges();
}

Как это происходит? Я почти уверен, что в EF 4 EF никогда не брал на себя такую ​​смелость: вы ДОЛЖНЫ были загружать, а затем удалять все связанные объекты вручную в коде.

Спасибо


person MrLane    schedule 18.06.2014    source источник


Ответы (2)


Entity framework по умолчанию имеет

OneToManyCascadeDelete

соглашение. Вот ссылка http://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.conventions.onetomanycascadedeleteconvention(v=vs.113).aspx

Таким образом, каскад инфраструктуры сущностей по умолчанию удаляет отношение «один ко многим».

Вы можете отключить это, отключив соглашение или явно отключив его для этого отношения через свободный API.

person Community    schedule 11.09.2014
comment
Присуждена награда, поскольку я не знал о соглашениях, поэтому, несмотря на то, что это не ответ, это все же было полезно. - person MrLane; 16.09.2014

Я нашел это на MSDN и я считаю, что это то, что происходит:

Когда первичный ключ основного объекта также является частью первичного ключа зависимого объекта, отношение является идентифицирующим отношением. В идентифицирующем отношении зависимый объект не может существовать без основного объекта. Это ограничение приводит к следующему поведению в идентифицирующей связи: Удаление основного объекта также приводит к удалению зависимого объекта. Это то же поведение, что и при указании OnDelete Action="Cascade" в модели отношения. Удаление отношения удаляет зависимый объект. Вызов метода Remove для EntityCollection помечает как отношение, так и зависимый объект для удаления.

Это то, что происходит в моей модели, где таблица UserComponent имеет составной первичный ключ: UserID, ComponentID, а столбец UserID является внешним ключом для UserID в таблице User.

person MrLane    schedule 16.09.2014