C# 实体框架删除对象问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1217052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Entity Framework Delete Object Problem
提问by Ibrahim AKGUN
i am getting "The object cannot be deleted because it was not found in the ObjectStateManager". while Deleting object.
我收到“无法删除该对象,因为在 ObjectStateManager 中找不到它”。在删除对象时。
here is codes ;
这是代码;
//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();
}}
采纳答案by jason
You need to attachthe object to the ObjectContext
. Try:
NEW_TABLE del = (NEW_TABLE)listView1.SelectedItems[0].Tag;
arama.Attach(del);
arama.DeleteObject(del);
arama.SaveChanges();
Attached objects are tracked by the ObjectContext
. This is needed for performing deletes and updates. You can read more about attaching objectson MSDN.
附加的对象由 跟踪ObjectContext
。这是执行删除和更新所必需的。您可以在 MSDN 上阅读有关附加对象的更多信息。
Edit to clarify attach/detach:
编辑以澄清附加/分离:
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
}
}
Also, you should wrap your use of ObjectContext
s in using
blocks.
此外,您应该将ObjectContext
s的使用包装在using
块中。
回答by Chrigl
In your method "Form1_Load" you create a FIRST instance of your "FirebirdEntity" context an fill the ListViewItem with entities selected from this context
在您的方法“Form1_Load”中,您创建了“FirebirdEntity”上下文的第一个实例,并使用从此上下文中选择的实体填充 ListViewItem
In your method "button3_Click" you create a NEW, SECOND instance of your "FirebirdEntity" context. Then you try to delete an entity in this SECOND context, which was selected in the FIRST context.
在您的方法“button3_Click”中,您创建了“FirebirdEntity”上下文的新的第二个实例。然后您尝试删除在第二个上下文中的实体,该实体是在第一个上下文中选择的。
Use the same instance of your context in both of your methods and everything will work fine.
在您的两种方法中使用相同的上下文实例,一切都会正常工作。
(Alternatively you can select the entity you want to delete a from your SECOND context and then delete this entity instead of the origin one)
(或者,您可以从第二个上下文中选择要删除的实体,然后删除该实体而不是原始实体)
回答by Daniel Casserly
usually for a delete in database i use this sort of linq query, always works unless you got a foreign key restraint:
通常对于数据库中的删除,我使用这种 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();
Hope this helps.
希望这可以帮助。
回答by Scott Moore
I ran a linq query within my DomainService methods and then deleted from the result, so while the first snippet below failed with error "The object cannot be deleted because it was not found in the ObjectStateManager", the second snippet worked.
我在我的 DomainService 方法中运行了一个 linq 查询,然后从结果中删除,所以虽然下面的第一个片段失败并出现错误“无法删除对象,因为在 ObjectStateManager 中找不到它”,但第二个片段有效。
public void DeleteSharedDoc(SharedDocs shareddoc)
{
this.ObjectContext.SharedDocs.DeleteObject(shareddoc);
}
This worked:
这有效:
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);
}
回答by granadaCoder
Assume I have an object called Department, with a surrogatekey DepartmentUUID
假设我有一个名为 Department 的对象,其代理键为 DepartmentUUID
DDL looks like this:
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
Now for the Entity Framework code. The important parts are: 1. Using the AttachTo method. 2. Creating a temporary object, and setting the primary-key value of it. (surrogate key).
现在是实体框架代码。重要的部分是: 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;
}
回答by vbullinger
The disgustingly terrible hack I used is this:
我使用的令人作呕的可怕黑客是这样的:
var attachedObject = _repository.GetObjectByKey(detachedObject.EntityKey);
Works for a lot of these issues. I was hoping to find a more elegant solution to this problem by coming here. This seems to do the trick.
适用于很多这些问题。我希望通过来到这里找到一个更优雅的解决方案。这似乎可以解决问题。