「ObjectStateManagerでオブジェクトが見つからなかったため、オブジェクトを削除できません。」というエラーが表示されます。
私のコードは:
protected MyEntities sqlEntities;
public virtual void Delete(TEntity entity)
{
System.Type t = typeof(TEntity);
sqlEntities.DeleteObject(entity);
sqlEntities.SaveChanges();
}
これは、エンティティがアタッチされていないことを意味します(同じコンテキストインスタンスによって読み込まれなかった)。これを試して:
protected MyEntities sqlEntities;
public virtual void Delete(TEntity entity)
{
sqlEntities.Attach(entity);
sqlEntities.DeleteObject(entity);
sqlEntities.SaveChanges();
}
ラディスラフ・ムンカによる答えのほんの少しの説明(これは受け入れられた答えであるべきです)。
私のような場合は、次のような形式のコードがあります。
using (var context = new MyDataContext())
{
context.MyTableEntity.Remove(EntytyToRemove);
var nrOfObjectsChanged = context.SaveChanges();
}
..それからあなたがしたいこと:
using (var context = new MyDataContext())
{
// Note: Attatch to the entity:
context.MyTableEntity.Attach(EntityToRemove);
context.MyTableEntity.Remove(EntityToRemove);
var nrOfObjectsChanged = context.SaveChanges();
}
おそらくこれは明白に思えますが、最初にcontextだけでなく、entityを指定する必要があることは明確ではありませんでした。
Kjartansの説明を適切に説明するために:
私が持っていた:
public Project DeleteProject(int id)
{
using (var context = new Context())
{
var p = GetProject(id);
context.Projects.Remove(p);
context.SaveChanges();
return p;
}
}
問題は、独自のメソッド(GetProject())を使用してエンティティを取得したことです(したがって、別のコンテキストを使用してエンティティをロードします)。
public Project GetProject(int id)
{
using (var context = new Context())
{
var project = context.Projects
.Include(p => p.Reports.Select(q => q.Issues.Select(r => r.Profession)))
.Include(p => p.Reports.Select(q => q.Issues.Select(r => r.Room)))
.SingleOrDefault(x => x.Id == id);
return project;
}
}
1つの解決策は、ロードされたエンティティをKjartanが示すようにアタッチすることであり、別の解決策は私のソリューションであり、同じコンテキスト内でエンティティをロードすることです。
public Project DeleteProject(int id)
{
using (var context = new Context())
{
var p = context.Projects.SingleOrDefault(x => x.Id == id);
if (p == null)
return p;
context.Projects.Remove(p);
context.SaveChanges();
return p;
}
}
私はこの質問がかなり古いことを知っていますが、複数のクラス/サービスからレジスタを削除し、それぞれが独自のデータベース接続コンテキストをインスタンス化していたため、上記のいずれも機能しませんでした。
私がそれを解決したのは、最初に作成されたコンテキストを、データベースにアクセスする残りのクラス/サービスに送信することでした。
たとえば、私のserviceA
はそのレジスターの一部を削除し、serviceB
およびserviceC
を呼び出してそれらのレジスターで同じことを行います。
次に、serviceA
のレジスタを削除し、serviceA
で作成されたコンテキストをパラメーターとしてserviceB
およびserviceC
に渡します。
このコードを書くことができます:
var x=yourquery.FirstOrDefault();
sqlEntities.DeleteObject(x);
sqlEntities.SaveChanges();
上記のいずれも機能しない場合は、次の解決策を試してください。
context.Entry(yourObject).State = System.Data.Entity.EntityState.Deleted; context.SaveChanges();
削除しようとしているリストにオブジェクトが存在することを確認する必要があります。次の条件を設定する必要があります
if(context.entity.contains(your object))
それを除く。
同等の複雑な条件がある場合エンティティクラスのequalメソッドをオーバーライドする必要があります同等の条件を設定して、拡張メソッドの正しい方法を取得する"entity.contains" =
私はこの問題を解決しました。以下のコードをコピーしてください:
sqlEntities.Attach(entity);
sqlEntities.Remove(entity);
sqlEntities.SaveChanges();
Remove(Entity)に渡すモデルがデータベースレコードと正確に同じであることを確認してください。
IdやDateなどのフィールドを使用せずにモデルを渡すことが可能な場合があります。フォームとして投稿する場合は、これらを@ html.Hiddenforに保持します。
最良の方法は、IDを渡し、Find(Id)メソッドを使用してエンティティを取得し、それをRemove(Entity)に渡すことです。
これが誰かを助けることを願っています。