Подтвердить что ты не робот

Как удалить отношения "многие ко многим" в Entity Framework без загрузки всех данных

Кто-нибудь знает, как удалить отношения "многие ко многим" в ADO.NET Entity Framework без необходимости загружать все данные? В моем случае у меня есть сущность Тема, которая имеет свойство Подписки, и мне нужно удалить одну подписку. Код myTopic.Subscriptions.Remove(...) работает, но мне нужно сначала загрузить все подписки (например, myTopic.Subscriptions.Load()), и я не хочу сделать это, потому что есть много (и я имею в виду лоты) подписки.

4b9b3361

Ответ 1

Вы можете присоединить() подписку, а затем удалить() это - обратите внимание, мы не используем Add() здесь, просто присоединяем, так что эффективно сообщаем EF, что мы знаем, что объект прикреплен в магазине, и прося его вести себя так, как будто это правда.

var db = new TopicDBEntities();
var topic = db.Topics.FirstOrDefault(x => x.TopicId == 1);

// Get the subscription you want to delete
var subscription = db.Subscriptions.FirstOrDefault(x => x.SubscriptionId == 2);
topic.Subscriptions.Attach(subscription); // Attach it (the ObjectContext now 'thinks' it belongs to the topic)
topic.Subscriptions.Remove(subscription); // Remove it
db.SaveChanges(); // Flush changes

Весь этот обмен, включая получение исходной темы из базы данных, отправляет эти 3 запроса в базу данных:

SELECT TOP (1) 
[Extent1].[TopicId] AS [TopicId], 
[Extent1].[Description] AS [Description]
FROM [dbo].[Topic] AS [Extent1]
WHERE 1 = [Extent1].[TopicId]


SELECT TOP (1) 
[Extent1].[SubscriptionId] AS [SubscriptionId], 
[Extent1].[Description] AS [Description]
FROM [dbo].[Subscription] AS [Extent1]
WHERE 2 = [Extent1].[SubscriptionId]


exec sp_executesql N'delete [dbo].[TopicSubscriptions]
where (([TopicId] = @0) and ([SubscriptionId] = @1))',N'@0 int,@1 int',@0=1,@1=2

чтобы он не вытягивал все подписки в любой момент.

Ответ 2

Вот как удалить без первой загрузки каких-либо данных. Это работает в EF5. Не уверен в более ранних версиях.

var db = new TopicDBEntities();

var topic = new Topic { TopicId = 1 };
var subscription = new Subscription { SubscriptionId = 2};
topic.Subscriptions.Add(subscription);

// Attach the topic and subscription as unchanged 
// so that they will not be added to the db   
// but start tracking changes to the entities
db.Topics.Attach(topic);

// Remove the subscription
// EF will know that the subscription should be removed from the topic
topic.subscriptions.Remove(subscription);

// commit the changes
db.SaveChanges(); 

Ответ 3

Один из способов - иметь сохраненный процесс, который удалит ваши дочерние записи непосредственно в БД и включит их в вашу модель EF; затем просто вызовите его из вашего DataContext.

Ответ 4

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

Учитывая:
[client] < --- many-to-many --- > [Лекарство]

Client objClient = new Client() { pkClientID = pkClientID };
EntityKey entityKey = _commonContext.CreateEntityKey("Client", objClient);
objClient.EntityKey = entityKey;
_commonContext.Attach(objClient); //just load entity key ...no db round trip

Medication objMed = new Medication() { pkMedicationID = pkMedicationID };
EntityKey entityKeyMed = _commonContext.CreateEntityKey("Medication", objMed);
objMed.EntityKey = entityKeyMed;
_commonContext.Attach(objMed);

objClient.Medication.Attach(objMed);
objClient.Medication.Remove(objMed); //this deletes
_commonContext.SaveChanges();

Ответ 5

Если внешние ключи установлены, ссылочная целостность должна автоматически выполняться через СУБД при удалении родительских объектов.

Если вы сначала используете код, насколько я узнал в учебнике MVA, ON DELETE CASCADE - это поведение по умолчанию, установленное EF6. Если вы запускаете DB сначала, вы должны изменить свою таблицу (ы)...

Вот ссылка: https://mva.microsoft.com/en-US/training-courses/implementing-entity-framework-with-mvc-8931?l=pjxcgEC3_7104984382 В Видео он упоминается в 20:00 вверх и в презентации слайдов он указан на странице 14.

Приветствия