Asp.net mvc ASP.NET MVC/EF4/POCO/Repository-如何更新关系?

Asp.net mvc ASP.NET MVC/EF4/POCO/Repository-如何更新关系?,asp.net-mvc,entity-framework-4,repository,poco,Asp.net Mvc,Entity Framework 4,Repository,Poco,我在评论和建议之间有一种1..*关系 我的模型的相关部分(也是EF4映射的POCO): UserContentService public void Update<TPost>(TPost post) where TPost : Post, new() { _repository.Update(post); // GenericRepository<Post> } 公共作废更新(TPost-post),其中TPost:post,new() { _repositor

我在评论建议之间有一种1..*关系

我的模型的相关部分(也是EF4映射的POCO):

UserContentService

public void Update<TPost>(TPost post) where TPost : Post, new()
{
   _repository.Update(post); // GenericRepository<Post>
}
公共作废更新(TPost-post),其中TPost:post,new()
{
_repository.Update(post);//GenericRepository
}
通用存储库-用作
通用存储库

public void Update<T2>(T2 entity) where T2 : class, new()
{
   // create stub entity based on entity key, attach to graph.

   // override scalar values
   CurrentContext.ApplyCurrentValues(CurrentEntitySet, entity);
}
公共无效更新(T2实体),其中T2:class,new()
{
//基于实体键创建存根实体,附加到图形。
//覆盖标量值
CurrentContext.ApplyCurrentValues(CurrentEntitySet,entity);
}

因此,每个建议都需要调用
Update
(或
Add
Delete
)存储库方法,具体取决于它是新的/修改的/删除的。

也许我需要更多的上下文,但有什么问题:

recommendations.Add(newRecomendation)
?

在答复评论时:

好吧,那你怎么了

SomeServiceOrRepository.AddNewRecommendation( newRecommendation )

最后一句话?你是说这两个问题

这一点也不难

总结一下我的回答,我认为你在“艰难地”做事,应该把重点放在发布与你试图完成的CRUD操作相对应的表单值上

如果一个新实体可以与您编辑的实体同时出现,那么您应该以不同的方式为它们添加前缀,以便模型绑定器可以对其进行处理。即使有多个新项,也可以使用相同的[0]语法,只需在“name”字段前面加上new或其他前缀即可

在这种情况下,很多时候您不能依赖实体框架图功能,因为从集合中删除实体并不意味着应该将其设置为删除

如果表单是不可变的,您也可以尝试使用ObjectSet的generized attach函数:

theContect.ObjectSet<Review>().Attach( review )
contect.ObjectSet().Attach(查看)

有很多方法可以解决这个问题。也许你可以发布你的控制器并查看代码?

使用分离的对象图是我最喜欢的EF缺点。只是屁股上的痛。首先你必须自己处理。EF不会帮你的。这意味着除了
Review
之外,您还必须发送一些有关所做更改的信息。当您将
Review
附加到上下文时,它会将
Review
all
Recommendation
所有关系设置为
未更改的状态
ApplyCurrentValues
仅适用于您已经找到的标量值。因此,您必须使用有关所做更改的附加信息,并通过使用
ObjectContext.ObjectStateManager.ChangeRelationshipState
将关系状态设置为
Added


我个人放弃了这种方法,我正在从DB加载对象图,首先将我的更改合并到附加图中并保存它


我回答了类似的问题。

我接受了@jfar的回答,因为他让我走上了正确的道路,但我认为为了其他人的利益,我应该在这里添加一个答案

未更新关系的原因如下:

1) 完全断开连接的场景。ASP.NET=无状态,新上下文为每个HTTP请求更新

2) 由MVC(模型绑定)创建的已编辑实体,但不存在于图形中

3) 在不进行更改跟踪的情况下使用POCO时,对实体执行
.Attach
会将其添加到图形中,但该实体和任何子关系将保持不变。

4) 我使用存根实体技巧和
ApplyCurrentValues
来更新实体,但这只适用于标量属性,而不适用于导航属性

因此-为了使上述功能正常工作,我必须明确地设置对象的
EntityState
(由于
ApplyCurrentValues
)和导航属性

还有一个问题-我如何知道导航属性是否已添加/修改/删除?我没有可以比较的对象-只有一个我知道是“编辑”的实体,但我不知道编辑了什么

因此,最终的解决方案是:

[HttpPost]
public ActionResult Edit(Review review)
{
   var existingReview = _service.FindById(review.Id); // review is now in graph.
   TryUpdateModel(existingReview); // MVC equivalent of "ApplyCurrentValues" - but works for ALL properties - including navigationals
   _unitOfWork.Commit(); // save changed
}
就这样。我甚至不需要我的
\u服务。Update
方法-因为我不再需要存根技巧-因为查看在带有检索的图表中,并且
ApplyCurrentValues
TryUpdateModel
替换

当然,现在,这不是一个并发证明解决方案

如果我加载“审阅编辑”视图,在我单击“提交”之前,其他人更改了审阅,我的更改可能会丢失

幸运的是,我有一个“最后的wins”并发模式,所以这对我来说不是问题


我喜欢POCO,但当您将无状态环境(MVC)和无更改跟踪结合在一起时,它们是一种痛苦。

这只会将项目添加到集合中,我还需要将该实体添加到图形中。记住-分离的上下文,POCO的,没有STE的。在这些场景中,EF不知道需要将此建议添加到DB中-我需要告诉它。作为回复-编辑。我如何知道应该添加/修改/删除该建议?我是否需要将所有“旧”建议与新建议进行比较?请看问题的最后一句。@jfar-已编辑的问题。阅读您的编辑-请记住我使用的是
ApplyCurrentValues
Attach(review)
只会修改标量值-而不是建议值。别担心-找到了。我认为它不适用于POCO的/分离的上下文。查看此声明:“如果您使用的是没有代理的POCO实体,则必须调用DetectChanges方法来同步对象上下文中的相关对象。如果您使用的是断开连接的对象,则必须手动管理同步。”Im使用断开连接的对象(根据表单值构造).@Ladislav Mrnka-我们在工作
SomeServiceOrRepository.AddNewRecommendation( int parentId, newRecommendation )
theContect.ObjectSet<Review>().Attach( review )
[HttpPost]
public ActionResult Edit(Review review)
{
   var existingReview = _service.FindById(review.Id); // review is now in graph.
   TryUpdateModel(existingReview); // MVC equivalent of "ApplyCurrentValues" - but works for ALL properties - including navigationals
   _unitOfWork.Commit(); // save changed
}