2009-08-01 18 views
14

「ObjectStateManagerにオブジェクトが見つかりませんでしたので、オブジェクトを削除できません。削除中。Entity Framework Delete Object問題

ここはコードです。

//first i am filling listview control. 
private void Form1_Load(object sender, EventArgs e) 
    { 
     FirebirdEntity asa = new FirebirdEntity(); 

     ObjectQuery<NEW_TABLE> sorgu = asa.NEW_TABLE; 

     foreach (var item in sorgu) 
     { 
      ListViewItem list = new ListViewItem(); 
      list.Text = item.AD; 
      list.SubItems.Add(item.SOYAD); 
      list.Tag = item; 
      listView1.Items.Add(list); 

     } 
//than getting New_table entity from listview's tag property. 
private void button3_Click(object sender, EventArgs e) 
    { 

      using (FirebirdEntity arama = new FirebirdEntity()) 
      { 

       NEW_TABLE del = (NEW_TABLE)listView1.SelectedItems[0].Tag; 
       arama.DeleteObject(del); 
       arama.SaveChanges(); 


      }} 

答えて

28

あなたはObjectContextにオブジェクトをattachする必要があります。試してください:

添付されているオブジェクトはObjectContextで追跡されます。これは、削除と更新を実行するために必要です。 MSDNのattaching objectsについてさらに読むことができます。

編集取り外し/取り付け明確にする:

private void Form1_Load(object sender, EventArgs e) { 
    FirebirdEntity asa = new FirebirdEntity(); 

    ObjectQuery<NEW_TABLE> sorgu = asa.NEW_TABLE; 
    foreach (var item in sorgu) { 
     asa.Detach(item); 
     // add to listView1 
    } 
} 

また、あなたはusingブロックでObjectContext Sの使用をラップする必要があります。あなたの方法で

+0

このエラーが発生しました。エンティティオブジェクトは、IEntityChangeTrackerの複数のインスタンスでは参照できません。 –

+0

エンティティを提供したObjectContextからデタッチする必要があります。そのオブジェクトをパラメータとしてObjectContext.Detachを呼び出します。 – jason

+0

今、私は "物体が傷ついていないことがわかりません"というGettinのエラーです。 : –

5

「Form1_Load」あなたは「FirebirdEntity」コンテキストの最初のインスタンスを作成し、ANあなたはNEW、あなたの2番目のインスタンスを作成する「をbutton3_Click」あなたの方法では、この文脈から

を選択したエンティティとのListViewItemを埋めます"FirebirdEntity"コンテキスト。次に、FIRSTコンテキストで選択されたこのSECONDコンテキストのエンティティを削除しようとします。

両方の方法でコンテキストの同じインスタンスを使用すれば、すべて正常に動作します。

いつも、私は、LINQクエリのこの種を使用してデータベースに削除するための通常

2

(またはあなたがあなたのSECONDコンテキストから削除して、起源の代わりに、このエンティティを削除したいエンティティを選択することができます)あなたが外国のキーの拘束を得ていない限り動作します:

int id = convert.toint32(some text field from the page); 
entity data = new entity(); 
var del = (from record in data.records 
      where record.id == id 
      select record).FirstOrDefault(); 
data.deleteObject(del); 
data.saveChanges(); 

希望することができます。

3

私は自分のDomainServiceメソッド内でlinqクエリを実行してから結果から削除しました。そのため、以下の最初のスニペットは "オブジェクトがObjectStateManagerに見つかりませんでした"というエラーで失敗しました。

public void DeleteSharedDoc(SharedDocs shareddoc) 
{ 
     this.ObjectContext.SharedDocs.DeleteObject(shareddoc); 
} 

これが働いた:surrogatekeyはDepartmentUUIDで

public void DeleteSharedDoc(SharedDocs shareddoc) 
{ 
var query = (from w in this.ObjectContext.SharedDocs 
      where w.UserShareName == shareddoc.UserShareName 
      && w.UserShareUsersEmail == shareddoc.UserShareUsersEmail 
      && w.DocumentId == shareddoc.DocumentId 
      select w).First(); 
this.ObjectContext.SharedDocs.DeleteObject(query); 
} 
2

が、私は部門と呼ばれるオブジェクトがあるとし

DDLは次のようになります。Entity Frameworkのための今すぐ

CREATE TABLE [dbo].[Department] 
    ( 
      DepartmentUUID [UNIQUEIDENTIFIER] NOT NULL 
     , DepartmentName varchar(24) not null 
     , CreateDate smalldatetime not null 
    ) 
GO 


ALTER TABLE [dbo].[Department] ADD CONSTRAINT PK_Department PRIMARY KEY NONCLUSTERED (DepartmentUUID) 
GO 

ALTER TABLE [dbo].[Department] ADD CONSTRAINT CK_DepartmentName_Unique UNIQUE (DepartmentName) 
GO 

ALTER TABLE [dbo].[Department] ADD CONSTRAINT [DF_Department_DepartmentUUID] DEFAULT (NEWSEQUENTIALID()) FOR DepartmentUUID 
GO 

ALTER TABLE [dbo].[Department] ADD CONSTRAINT [DF_Department_CreateDate] DEFAULT (CURRENT_TIMESTAMP) FOR CreateDate 
GO 

をコード。重要な部分は次のとおりです。 1. AttachToメソッドを使用する。 2.一時オブジェクトを作成し、それのプライマリキー値を設定します。 (代理キー)。これらの問題の多くのために

var attachedObject = _repository.GetObjectByKey(detachedObject.EntityKey); 

作品:

public int DeleteDepartment(Guid departmentUUID) 
{ 

    int returnValue = 0; 

    Department holder = new Department(); 
    holder.DepartmentUUID = departmentUUID; // DepartmentUUID is the primary key of this object (entity in the db) 

    using (MyContectObject context = new MyContectObject()) 
    { 
     context.AttachTo("Departments", holder); 

     context.DeleteObject(holder); 

     int numOfObjectsAffected = context.SaveChanges(); 
     returnValue = numOfObjectsAffected; 

     context.Dispose(); 
    } 

    return returnValue; 

} 
+2

最後の4行は次のようにする必要があります:return context.SaveChanges();またreturnValue変数も削除してください。 –

+0

一部のフレームワークは、削除されたオブジェクトを返します(http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html#remove(int)。 )いくつかのフレームワークは、影響を受けた行の数を返します。いくつかのフレームワークはvoidを返します。あなたがそれをしないというだけで、私が正当な必要がないというわけではありませんt。しかし、はい、私のコードは、 "returnValue = context.SaveChanges();"を使用してスリム化することができます。 (<<ただ、私が手に入ることができないことを示すために)はい、あなたがそれを選択すると、コードをいくつか削除することができます。簡潔性よりも可読性が好まれることがあります。 – granadaCoder

+0

はい、読みやすさです。このコードは可能な限り醜いです。そして、読むことができません。それが私の言いたいことです。 –

1

私が使用うんざりひどいハックはこれです。私はここに来て、この問題に対するより洗練された解決策を見つけることを望んでいました。これはトリックを行うようだ。

関連する問題