我收到“无法删除对象,因为在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();
}}
答案 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);
适用于很多这些问题。来到这里,我希望能找到更优雅的解决方案。这似乎可以解决问题。