ObjectStateManager中已存在具有相同键的对象(具有指定字段)

时间:2013-03-11 02:53:10

标签: asp.net asp.net-mvc entity-framework web-applications

我知道这个问题已被问了很多次,但我认为我指定修改字段这一事实让我有点难以解决。这是我的更新方法(在存储库中):

        public Folder UpdateFolder(Folder folder)
        {
            _db.Folders.Attach(folder); // error happens here
            var entry = _db.Entry(folder);
            entry.Property(e => e.Title).IsModified = true;
            SaveChanges();
            return entry.Entity;
        }

当我尝试连接时,我得到“具有相同密钥的对象已经存在”。如果我删除该行,我得到“类型的实体”文件夹“在此上下文中不存在”。

这是我从(测试方法)调用它的地方:

        homeFolder = _dtoServices.AddFolder(new FolderDto
            {
                Title = "Home Folder"
            });
        Assert.AreEqual(_dtoServices.GetHomeData().TotalFolders, 1);

        // Check Folder
        Assert.AreEqual(_dtoServices.GetFolder(homeFolder.FolderId).Details, "Home Folder");

        // Update Folder, Check Folder
        homeFolder.Title = "Updated";
        _dtoServices.UpdateFolder(homeFolder); // HERE
        Assert.AreEqual(_dtoServices.GetFolder(homeFolder.FolderId).Details, "Updated");

在我的DtoServices中:

        public FolderDto UpdateFolder(FolderDto folderDto)
        {     
            var test = _repository.UpdateFolder(folderDto.ToEntity());
            return null;
        }

在我的FolderDto中:

public class FolderDto
{
    public FolderDto()
    {
    }

    public FolderDto(Folder folder)
    {
        FolderId = folder.FolderId;
        Title = folder.Title;          
    }

    [Key]
    public int FolderId { get; set; }

    [Required]
    public string Title { get; set; }

    public Folder ToEntity()

     {
        var folder = new Folder
        {
            FolderId = FolderId,
            Title = Title,
        };
        return folder;
    }
 }

知道为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

问题很可能在这里:folderDto.ToEntity()。我想在_dtoServices.AddFolder中您创建了一个Folder实体并将其添加到上下文中,然后调用SaveChanges,然后将生成的Id放入返回的homeFolder中DTO。实体Folder仍然附加到上下文,并且SaveChanges处于州Unchanged之后。

UpdateFolder中,通过调用folderDto.ToEntity(),您可以创建一个新的实体实例var folder = new Folder...,其中包含您从AddFolder返回的相同ID。然后,将此新实例附加到相同的上下文中,其中具有相同键的AddFolder的旧实例仍附加到==>另一个“具有相同键的对象”==>异常。

在附加新实体之前分离旧实体,或使用Find检查是否已存在具有相同密钥的实体。如果是,请更新实体,不要附加其他对象。