23

EntityFramework 5を使用してオブジェクトを削除しようとしていますが、このエラーが発生します。 ObjectStateManagerでオブジェクトが見つからなかったため、オブジェクトを削除できません 。EF5に存在しないメソッドを
使用しています。誰かが私が欠けているものを助けることができますか?Remove()DeleteObject()

これは削除では機能しません

localDb.Customers.Remove(new Customer() { CustomerId = id });
                localDb.SaveChanges();

状態を削除済みに変更するためにmsdnから試したもう1つのこと。しかし、ここでは、すべてのフィールドが存在する必要があるというエラーが表示されます。完全なレコードを取得してから削除する必要がありますか?

var customer = new Customer(){ CustomerId = id };
                localDb.Customers.Attach(customer);

                localDb.Entry(customer).State = EntityState.Deleted;
                localDb.SaveChanges();

入力はありますか?

4

5 に答える 5

37

データベースから行をフェッチしてから削除することもできますが、これによりデータベースへのラウンドトリップが2回発生します。

1回のヒットでそれを実行したい場合はAttach、エンティティがコンテキストにまだロードされていない限り、2番目のバージョンが機能します。

発生するエラーは、データベースへの書き込み前に実行されるEF検証が原因で発生します。

次のように一時的にオフにすることができます。

bool oldValidateOnSaveEnabled = localDb.Configuration.ValidateOnSaveEnabled;

try
{
  localDb.Configuration.ValidateOnSaveEnabled = false;

  var customer = new Customer { CustomerId = id };

  localDb.Customers.Attach(customer);
  localDb.Entry(customer).State = EntityState.Deleted;
  localDb.SaveChanges();
}
finally
{
  localDb.Configuration.ValidateOnSaveEnabled = oldValidateOnSaveEnabled;
}
于 2013-03-26T13:25:37.320 に答える
18

データベースからオブジェクトを取得した場合、そのオブジェクトはすでにコンテキストにアタッチされているため、次の方法で削除できます。

db.myTable.Remove(model);

ただし
、データベースへの2回のトリップを回避するために、モデルを編集または削除ビューから受け取ったばかりか、自分で生成した場合、EFはそれを認識せず、上記の行でエラーが発生します(..ObjectStateManagerにありません..)。状態を「削除済み」に設定して、次の方法でEFに通知します。

//generate it yourself if not posted from edit/delete view
//var model = new Model { Id = 123 };

//set to delete
db.Entry(model).State = EntityState.Deleted;
db.SaveChanges();
于 2014-09-02T17:56:09.427 に答える
4

あなたはこれをすることができますか?

var customer = localDb.Customers.Single(o => o.CustomerId == id);
localDb.Customers.Remove(customer);
localDb.SaveChanges();
于 2013-03-26T13:25:32.423 に答える
1
public T Delete<T>(T obj) where T : class
        {
            T existing = context.Set<T>().Find(GetKeys(obj, context));

            if (existing != null)
            {
                context.Set<T>().Remove(existing);
                context.SaveChanges();
                return existing;
            }
            return null;
        }

private object[] GetKeys<T>(T entity, DbContext context) where T : class
        {
            ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
            ObjectSet<T> set = objectContext.CreateObjectSet<T>();
            var keyNames = set.EntitySet.ElementType
                                                        .KeyMembers
                                                        .Select(k => k.Name).ToArray();
            Type type = typeof(T);

            object[] keys = new object[keyNames.Length];
            for (int i = 0; i < keyNames.Length; i++)
            {
                keys[i] = type.GetProperty(keyNames[i]).GetValue(entity, null);
            }
            return keys;
        }
于 2016-05-24T08:56:24.463 に答える
0

私はこの質問がかなり古いことを知っていますが、一度に複数のクラス/サービスからレジスタを削除し、それぞれが独自のデータベース接続コンテキストをインスタンス化していたため、上記のどれもうまくいきませんでした。

それを解決するために私がしたことは、最初に作成されたコンテキストを、データベースにアクセスする残りのクラス/サービスに送信することでした。

たとえば、serviceAレジ​​スターの一部を削除して呼び出しserviceBserviceCそれらのレジスターで同じことを行うつもりでした。

次に、レジスタを削除し、 toとserviceAに作成されたコンテキストをパラメータとして渡します。serviceAserviceBserviceC

于 2016-12-09T12:48:57.390 に答える