Entity Framework Проблема удаления объекта - PullRequest
14 голосов
/ 01 августа 2009

Я получаю «Объект не может быть удален, потому что он не был найден в 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 ]

28 голосов
/ 01 августа 2009

Вам необходимо прикрепить объект к 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 s в блоках using.

5 голосов
/ 30 сентября 2009

В вашем методе "Form1_Load" вы создаете ПЕРВЫЙ экземпляр вашего контекста "FirebirdEntity" и заполняете ListViewItem объектами, выбранными из этого контекста

В вашем методе «button3_Click» вы создаете НОВЫЙ, ВТОРОЙ экземпляр вашего контекста «FirebirdEntity». Затем вы пытаетесь удалить объект в этом втором контексте, который был выбран в первом контексте.

Используйте один и тот же экземпляр вашего контекста в обоих ваших методах, и все будет работать нормально.

(В качестве альтернативы вы можете выбрать сущность, которую вы хотите удалить из вашего ВТОРОГО контекста, а затем удалить эту сущность вместо исходного)

3 голосов
/ 27 мая 2011

Я выполнил запрос 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);
}
2 голосов
/ 10 сентября 2011

Предположим, у меня есть объект с именем 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;

}
2 голосов
/ 24 ноября 2010

обычно для удаления в базе данных я использую этот запрос 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();

Надеюсь, это поможет.

1 голос
/ 23 августа 2012

отвратительно ужасный хак, который я использовал, это:

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

Работает для многих из этих проблем. Я надеялся найти более элегантное решение этой проблемы, придя сюда. Это, кажется, делает трюк.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...