19

すべてのデータをロードすることなく、ADO.NET Entity Framework で多対多の関係を削除する方法を知っている人はいますか? 私の場合、サブスクリプション プロパティを持つエンティティトピックがあり単一のサブスクリプションを削除する必要があります。コードmyTopic.Subscriptions.Remove(...)は機能しますが、最初にすべてのサブスクリプションをロードする必要があります (例: myTopic.Subscriptions.Load() )。たくさんあるので、それをしたくありません(つまり、たくさんあります)。サブスクリプションの。

4

5 に答える 5

27

サブスクリプションを 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

そのため、どの時点でもすべてのサブスクリプションを取得しているわけではありません。

于 2009-04-16T22:02:02.990 に答える
4

これは、最初にデータをロードせずに削除する方法です。これは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(); 
于 2013-03-08T12:48:44.590 に答える
2

1 つの方法は、子レコードを DB で直接削除し、それを EF モデルに含めるストアド プロシージャを用意することです。次に、DataContext から呼び出すだけです。

于 2009-04-16T17:02:17.470 に答える
1

これが私の例です...外部キーを知っていて、dbラウンドトリップをしたくない場合。
これが誰かに役立つことを願っています...

与えられた:
[クライアント]<---多対多--->[薬]

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();
于 2009-08-21T09:14:55.790 に答える