实体框架删除对象问题

时间:2009-08-01 17:21:55

标签: c# entity-framework ado.net

我收到“无法删除对象,因为在ObjectStateManager中找不到该对象”。删除对象时。

这是代码;

//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();


            }}

6 个答案:

答案 0 :(得分:28)

您需要attach对象ObjectContext。尝试:

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

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
    }
}

另外,您应该在ObjectContext块中包含using s的使用。

答案 1 :(得分:5)

在您的方法“Form1_Load”中,您创建了一个“FirebirdEntity”上下文的FIRST实例,并使用从此上下文中选择的实体填充ListViewItem

在您的方法“button3_Click”中,您将创建“FirebirdEntity”上下文的NEW,SECOND实例。然后,您尝试删除在第一个上下文中选择的SECOND上下文中的实体。

在两种方法中使用相同的上下文实例,一切都会正常工作。

(或者,您可以从SECOND上下文中选择要删除的实体,然后删除此实体而不是原始实体)

答案 2 :(得分:3)

我在我的DomainService方法中运行了一个linq查询,然后从结果中删除了,所以当下面的第一个代码段失败时出现错误“无法删除该对象,因为在ObjectStateManager中找不到该对象”,第二个代码段工作正常。 / p>

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

这有效:

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);
}

答案 3 :(得分:2)

通常对于数据库中的删除我使用这种linq查询,除非你得到一个外键约束,否则总是有效:

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();

希望这有帮助。

答案 4 :(得分:2)

假设我有一个名为Department的对象,带有代理键DepartmentUUID

DDL看起来像这样:

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

现在为Entity Framework代码。重要的部分是: 1.使用AttachTo方法。 2.创建临时对象,并设置它的主键值。 (代理键)。

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;

}

答案 5 :(得分:1)

我使用的令人作呕的糟糕黑客是:

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

适用于很多这些问题。来到这里,我希望能找到更优雅的解决方案。这似乎可以解决问题。