Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot attach an entity that already exists

Tags:

c#

linq-to-sql

I get this error whenever i try to update one of my models. The update is pretty simple:

Todo bn = service.GetTodos().Single(t => t.todoId == 1);
bn.Note.noteTitle = "Something new";
service.SaveTodo(bn);

And the models have this kind of structure:

  • A Todo has a Note
  • A Todo has a list of Tasks

I have my service's SaveTodo look a little something like this:

public void SaveTodo ( TodoWrapper note )
{
    using (Repository repo = new Repository(new HpstrDataContext()))
    {
        if (note != null)
        {
            Todo todo = repo.Todos.SingleOrDefault(t => t.todoId == note.todoId);
            if (todo == null)
            {
                todo = new Todo();
                todo.Note = new Note();
            }
            todo.dueDate = note.dueDate;
            todo.priority = (short)note.priority;

            todo.Note.isTrashed = note.Note.isTrashed;
            todo.Note.permission = (short)note.Note.permission;
            todo.Note.noteTitle = note.Note.noteTitle;

            repo.SaveTodo(todo);
        }
    }
}

And the Repository's SaveTodo method is pretty simple and looks like this:

public void SaveTodo ( Todo todo )
{
    if (todo.Note.noteId == 0)
    {
        dc.NoteTable.InsertOnSubmit(todo.Note);
    } else
    {
        dc.NoteTable.Attach(todo.Note);
        dc.NoteTable.Context.Refresh(RefreshMode.KeepCurrentValues , todo.Note);
    }
    if (todo.todoId == 0)
    {
        dc.TodoTable.InsertOnSubmit(todo);
    } else
    {
        dc.TodoTable.Attach(todo);
        dc.TodoTable.Context.Refresh(RefreshMode.KeepCurrentValues , todo);
    }
    dc.SubmitChanges();
}

The error is being thrown at this line in the Repository: dc.NoteTable.Attach(todo.Note);. I've tried a lot of different things to get this to work but nothing seems to work.

Any help would be greatly appreciated

like image 613
Collin O'Connor Avatar asked Jan 18 '26 00:01

Collin O'Connor


1 Answers

So i solved the problem (hopefully). In my Repository, i changed the SaveTodo to look like this

public void SaveTodo ( TodoWrapper note )
{
    using (Repository repo = new Repository(new HpstrDataContext()))
    {
        if (note != null)
        {
            Todo todo = repo.Todos.SingleOrDefault(t => t.todoId == note.todoId);
            if (todo == null)
            {
                todo = new Todo();
                todo.Note = new Note();
            }
            todo.dueDate = note.dueDate;
            todo.priority = (short)note.priority;
            todo.Note.isTrashed = note.Note.isTrashed;
            todo.Note.permission = (short)note.Note.permission;
            todo.Note.noteTitle = note.Note.noteTitle;
            foreach (TaskWrapper item in note.Tasks)
            {
                Task t = repo.Tasks.SingleOrDefault(task => task.tasksId == item.taskId);
                if (t == null)
                {
                    t = new Task();
                }
                t.Todo = todo;
                t.isCompleted = item.isCompleted;
                t.content = item.content;
                repo.SaveTask(t);
            }
        }
    }
}

If anybody was wondering, the wrappers are used as wrappers (no way) for the entities with wcf.

And my save task looked like this:

public void SaveTask ( Task task )
{
    if (task.tasksId == 0)
    {
        dc.TaskTable.InsertOnSubmit(task);
    } else
    {
        dc.TaskTable.Context.Refresh(RefreshMode.KeepCurrentValues , task);
    }
    dc.SubmitChanges();
}

I got rid of the Attach because I already pull out the Todo when calling the single or default statement so it was already attached to the database. So the error was correct because this entity was already attached to the database. If i had made a new Todo instead of grabbing the one out the database, the attach would have worked. Hope this helps out anyone who stumbles upon this

like image 134
Collin O'Connor Avatar answered Jan 19 '26 15:01

Collin O'Connor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!