无法附加已存在的实体

时间:2011-06-15 04:34:44

标签: c# linq-to-sql

每当我尝试更新我的某个模型时,都会收到此错误消息。更新非常简单:

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

模型有这种结构:

  • Todo有注意
  • Todo有一个任务列表

我的服务的SaveTodo看起来像这样:

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);
        }
    }
}

Repository的SaveTodo方法很简单,看起来像这样:

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();
}

在存储库中的这一行抛出错误:dc.NoteTable.Attach(todo.Note);。我已经尝试了许多不同的东西来使这个工作,但似乎没有任何工作。

非常感谢任何帮助

1 个答案:

答案 0 :(得分:2)

所以我解决了这个问题(希望如此)。在我的存储库中,我将SaveTodo更改为如下所示

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);
            }
        }
    }
}

如果有人想知道,包装器被用作wcf实体的包装器(没办法)。

我的保存任务看起来像这样:

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

我摆脱了Attach,因为我在调用single或default语句时已经拔出了Todo,因此它已经附加到数据库中了。所以错误是正确的,因为该实体已经附加到数据库。 如果我制作了一个新的Todo而不是从数据库中取出一个,那么附件就可以了。希望这有助于任何偶然发现此事的人