2012-02-27 47 views
0

我一直试图找出一个很好的解决方案,大部分的下午,但无济于事。从分离状态删除关系

当我使用实体框架(EF)查询数据时,我总是使用MergeOption.NoTracking,因为我不想在我的视图中使用数据库对象进行显示。我最终将EF生成的POCO类映射到视图模型中,这些视图模型具有可爱的小属性,如必需的,显示名称等。当我需要进行更新时,我最终将我的视图模型映射回生成的类通过实体框架并执行创建或更新操作。

我试图找到一种简单的方法来删除与我的对象的关系,但由于它们是分离的,我一直没能找到办法做到这一点。我看到有人推荐附加和删除对象,但由于我的对象被分离了,所以不起作用(它导致信息Attach is not a valid operation when the source object associated with this related end is in an added, deleted, or detached state. Objects loaded using the NoTracking merge option are always detached.的异常)。

这里是我当前的代码示例:

//Find the records that need to be deleted. 
    var productVersionsToDelete = (from pv in existingDownloadFile.ProductVersions 
            where !selectedVersions.Contains(pv.Id) 
            select pv).ToList(); 

    foreach (var productVersionToDelete in productVersionsToDelete) { 
     existingDownloadFile.ProductVersions.Attach(productVersionToDelete); 
     existingDownloadFile.ProductVersions.Remove(productVersionToDelete); 
    } 

没有人有从分离状态删除对象的建议?

回答

1

问题是,一旦调用attach,整个对象图就会被附加。给定一个DbContext称为context,这应该工作将是以下的例子:

// Attach the download file to the context set (this will attach all ProductVersions 
context.DownloadFiles.Attach(existingDownloadFile); 

//Find the records that need to be deleted. 
var productVersionsToDelete = (from pv in existingDownloadFile.ProductVersions 
           where !selectedVersions.Contains(pv.Id) 
           select pv).ToList(); 

foreach (var productVersionToDelete in productVersionsToDelete) 
    existingDownloadFile.ProductVersions.Remove(productVersionToDelete); 

context.SaveChanges(); 

这是假定DownloadFiles是属性的名字写在你DbContext暴露匹配的existingDownloadFile类型哪些实体。

你得到的例外是因为一旦你附加ProductVersion,它附加相关的existingDownloadFile,它只能附加一次。

+0

谢谢你的帮助,那就是诀窍。一个问题,但。我的情况下'existingDownloadFile'没有附加。我的所有物品都处于分离状态。发生错误是因为关系链中的顶级对象需要连接吗?我仍然不确定自己是否裹过脑袋,为什么会发生错误。 – 2012-02-28 00:18:30

+0

我相信当你附加第一个'productVersionToDelete'时,它有一个引用回到'existingDownloadFile',这会导致它被连接。下一次调用attach时,它试图再次附加'existingDownloadFile',但它第一次连接,所以发生错误。 – Lukazoid 2012-02-28 00:20:11