Как удалить отношение «многие ко многим» в Entity Framework без загрузки всех данных - PullRequest
19 голосов
/ 16 апреля 2009

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

Ответы [ 5 ]

27 голосов
/ 17 апреля 2009

Вы можете прикрепить () подписку, затем удалить () ее - заметьте, мы здесь не используем 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

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

4 голосов
/ 08 марта 2013

Это как удалить без предварительной загрузки каких-либо данных. Это работает в 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(); 
2 голосов
/ 16 апреля 2009

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

1 голос
/ 21 августа 2009

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

Дано:
[клиент] <--- многие ко многим ---> [лекарства]

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();
0 голосов
/ 07 апреля 2016

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

Если вы сначала используете код, насколько я узнал в руководстве по 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 .

Приветствия

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...