web-dev-qa-db-ja.com

最初にオブジェクトを読み込まずにEntity Frameworkモデルからオブジェクトを削除するにはどうすればよいですか?

この質問の答えはどこかで見たことがあると思いますが、SOまたはgoogleで検索を数回行っても見つからなかったので、とにかくもう一度質問します...

Entity Frameworkでは、データオブジェクトを削除する唯一の方法は、

MyEntityModel ent = new MyEntityModel();
ent.DeleteObject(theObjectToDelete);
ent.SaveChanges();

ただし、この方法では、オブジェクトを削除するために、この場合は最初にコントローラにオブジェクトをロードする必要があります。インスタンスのIDのみを参照するビジネスオブジェクトを削除する方法はありますか?

LinqまたはLambda式を使用するよりスマートな方法があれば、それも問題ありません。ただし、主な目的は、データを削除するためだけにデータをロードしないようにすることです。

39
Tomas Aschan

Entity FrameworkがLinq to EntitiesとEntity SQLの両方をサポートしていることは知っておく価値があります。多くのレコードに影響を与える可能性のある削除または更新を実行したい場合は、ExecuteNonQueryと同等のものを使用できます。

エンティティSQLでは、次のようになります。

   Using db As New HelloEfEntities

        Dim qStr = "Delete " & _
                  "FROM Employee"
        db.ExecuteStoreCommand(qStr)
        db.SaveChanges()
    End Using

この例では、dbは私のObjectContextです。また、ExecuteStoreCommand関数はオプションのパラメーター配列を取ることに注意してください。

19
John Wigger

私は this post を見つけました、これはレコードを削除するためのより良い方法は本当にないことを述べています。与えられた説明は、このレコードに固有のすべての外部キー、リレーションなども削除されるため、EFはレコードに関する正しい情報を持っている必要があるということです。データを何度もロードしないとこれを実現できないのかと私は戸惑いましたが、それが頻繁に発生することはないので、(今のところ)気にしないことを決定しました。

この問題の解決策がある場合は、遠慮なくお知らせください=)

8
Tomas Aschan

EntityKeyを再計算してエンティティを偽装する方法があります。少しハックのように見えますが、EFでこれを行う唯一の方法かもしれません。

フェッチなしの削除に関するブログ記事

4
biozinc

同じIDのオブジェクトを作成し、それを削除に渡すことができますが、複雑な関係があり、それ以上のものが必要な場合は、単純なオブジェクトに適しています。

                var user = new User { ID = 15 };
                context.Entry(user).State = EntityState.Deleted;
                context.SaveChanges();
4
CMS

あらかじめお詫び申し上げますが、あなたの目標を質問させていただきます。

オブジェクトを読み取らずに削除した場合、オブジェクトの削除を確認してから実際に削除するまでの間に、別のユーザーがオブジェクトを変更したかどうかはわかりません。 「プレーンな古いSQL」では、これは次のようになります。

DELETE FROM FOO
WHERE ID = 1234

もちろん、ほとんどの人は実際にはこれをしていません。代わりに、彼らは次のようなことをします:

DELETE FROM FOO
WHERE ID = 1234
  AND NAME = ?ExpectedName AND...

重要なのは、別のユーザーがその間にレコードを変更した場合、削除は失敗する(何もしない)ことです。

これにより、問題をより適切に説明できます。EntityFrameworkを使用する場合、2つの解決策があります。

  1. Deleteメソッドの既存のインスタンスで、プロパティの期待値を比較し、同じ場合は削除します。この場合、Entity Frameworkは、プロパティ値を含むDELETEステートメントを作成します。

  2. IDEと他のプロパティ値の両方を受け入れるストアドプロシージャを作成し、それを実行します。

4
Craig Stuntz

Entity Framework 5には Entity Framework Extended Library があります。 NuGetで利用できます。それからあなたは次のようなものを書くことができます:

context.Users.Delete(u => u.Id == id);

また、一括削除にも役立ちます。

3
acarlon
var toDelete = new MyEntityModel{
    GUID = guid,
    //or ID = id, depending on the key
    };
Db.MyEntityModels.Attach(toDelete);
Db.MyEntityModels.DeleteObject(toDelete);
Db.SaveChanges();

キーに複数の列が含まれている場合は、すべての値(GUID、columnX、columnYなど)を指定する必要があります。

何かおかしいと感じた場合は、ジェネリック関数の here も参照してください。

3
tymtam