有谁知道如何在 ADO.NET Entity Framework 中删除多对多关系而无需加载所有数据?在我的情况下,我有一个具有属性订阅的实体主题,我需要删除一个订阅。代码myTopic.Subscriptions.Remove(...)有效,但我需要先加载所有订阅(例如myTopic.Subscriptions.Load()),我不想这样做,因为有很多(我的意思是很多)的订阅。
5 回答
您可以 Attach() 订阅,然后 Remove() 它 - 请注意,我们在这里没有使用 Add(),只是 Attach,因此我们有效地告诉 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
所以它不会在任何时候取消所有订阅。
这是在不首先加载任何数据的情况下删除的方法。这适用于 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();
一种方法是拥有一个存储过程,它将直接在数据库中删除您的子记录并将其包含在您的 EF 模型中;然后只需从您的 DataContext 调用它。
这是我的示例...我知道外键并且我不想进行数据库往返。
我希望这可以帮助别人...
给定:
[客户端]<---多对多--->[药物]
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();
如果设置了外键,则在删除父实体时,参照完整性应通过 DBMS 本身自动完成。
如果您首先使用代码,据我在 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 页上所说的幻灯片演示。
干杯