Проблема с объектом Entity Framework
Я получаю "Объект нельзя удалить, потому что он не найден в 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 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();
}}
Ответы
Ответ 1
Вам нужно attach объект в ObjectContext
. Попробуйте:
NEW_TABLE del = (NEW_TABLE)listView1.SelectedItems[0].Tag;
arama.Attach(del);
arama.DeleteObject(del);
arama.SaveChanges();
Прикрепленные объекты отслеживаются с помощью ObjectContext
. Это необходимо для выполнения удалений и обновлений. Вы можете больше узнать о прикреплении объектов к MSDN.
Изменить, чтобы уточнить прикрепление/отсоединение:
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
.
Ответ 2
В вашем методе Form1_Load вы создаете FIRST-экземпляр вашего контекста "FirebirdEntity", заполните ListViewItem сущностями, выбранными из этого контекста.
В вашем методе "button3_Click" вы создаете новый, второй экземпляр вашего контекста "FirebirdEntity". Затем вы пытаетесь удалить объект в этом SECOND-контексте, который был выбран в FIRST-контексте.
Используйте один и тот же экземпляр вашего контекста в обоих ваших методах, и все будет работать нормально.
(В качестве альтернативы вы можете выбрать объект, который хотите удалить a из своего SECOND-контекста, а затем удалить этот объект вместо исходного)
Ответ 3
Я запустил linq-запрос в своих методах DomainService и затем удалил из результата, поэтому, в то время как первый фрагмент ниже с ошибкой "Объект не может быть удален, потому что он не был найден в ObjectStateManager", второй фрагмент работал.
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);
}
Ответ 4
обычно для удаления в базе данных я использую этот тип запроса 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();
Надеюсь, что это поможет.
Ответ 5
Предположим, у меня есть объект, называемый Департамент, с суррогатной клавишей 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. Важными частями являются:
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;
}
Ответ 6
Отвратительно ужасный хак, который я использовал, таков:
var attachedObject = _repository.GetObjectByKey(detachedObject.EntityKey);
Работает для многих из этих проблем. Я надеялся найти более элегантное решение этой проблемы, придя сюда. Это похоже на трюк.