ASP.NET MVC / EF4 / POCO / Repository - 如何更新关系? [英] ASP.NET MVC / EF4 / POCO / Repository - How to Update Relationships?

查看:146
本文介绍了ASP.NET MVC / EF4 / POCO / Repository - 如何更新关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有评论建议之间的1 .. *关系。



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

  public class Review 
{
public ICollection< ;建议>建议{get;组;
}

编辑视图上,我代表



当我尝试添加新建议时,作为一组复选框。 (例如检查另一个框),没有任何事情发生 - 我知道为什么...



我使用存根技术更新我的实体 - 例如我创建一个实体使用相同的键,将其附加到图形,然后执行 ApplyCurrentValues 。但是这只适用于标量属性,而不适用于导航属性。



我发现这个StackOverflow问题看起来不错,但是我试图找出如何使它与POCO / Repository(和ASP.NET MVC - 分离)



当我使用POCO时, review.Recommendations 是一个 ICollection< ;建议> ,所以我不能做 review.Recommendations.Attach 。我还没有使用自我跟踪实体,所以我需要手动使用图表/变更跟踪 - 直到现在还没有出现问题。



所以你可以可视化的方案:



评论:




  • 建议( ICollection<推荐> ):


    • 推荐(推荐

    • 建议二(建议

    li>


如果在编辑视图中显示,则已经选中了两个复选框。第三个(代表RecommendationThree)是未选中



但是,如果我选中该框,上述模型将变为:



评论:




  • 建议( ICollection<推荐> ):


    • 推荐单元(建议

    • 建议二(建议

    • 建议三(建议




所以我需要把SuggestThree作为一个新实体



我需要隐藏的字段来比较现有实体发布的数据吗?或者我应该将实体存储在TempData中,并将其与发布的实体进行比较?



编辑



为了避免混淆,这里是完整的应用程序堆栈调用:



ReviewController

  [HttpPost] 
public ActionResult编辑(评论)
{
_service.Update(review); // UserContentService
_unitOfWork.Commit();
}

UserContentService


pre $ public void Update< TPost>(TPost post)其中TPost:Post,new()
{
_repository.Update(post); // GenericRepository< Post>
}

GenericRepository - 用作 GenericRepository< Post> ;

  public void Update< T2>(T2 entity)其中T2:class ,new()
{
//根据实体键创建存根实体,附加到图形。

//覆盖标量值
CurrentContext.ApplyCurrentValues(CurrentEntitySet,entity);
}

所以,更新(或添加删除)需要为每个建议调用存储库方法,这取决于新的/修改/删除

解决方案

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

  recommendations.Add(newRecomendation)



在回复评论:



好,所以有什么问题

  SomeServiceOrRepository.AddNewRecommendation(newRecommendation)

  SomeServiceOrRepository.AddNewRecommendation(int parentId,newRecommendation)

最后一句话?你的意思是两个问题?



这不应该很难。



为了总结我的答案,我认为您正在做的事情艰难的方式,并且应该专注于发布与您尝试完成的CRUD操作相对应的表单值。



如果一个新的实体可以和您编辑的实体同时进入,那么您应该以不同的方式前缀它们,以便模型绑定器可以在其上接收。即使您有多个新项目,您也可以使用相同的[0]语法在名称字段的前面添加新的或某些东西。



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



如果表单是不可变的,您还可以尝试使用ObjectSet中的生成的附加功能:

  theContect.ObjectSet< Review>()。附加(评论)

也许你可以发布控制器并查看代码?


I have a 1..* relationship between Review and Recommendations.

The relevant portion of my model (which is also the POCO mapped by EF4):

public class Review
{
   public ICollection<Recommendations> Recommendations { get; set; }
}

On an Edit View, i represent the Recommendations as a set of checkboxes.

When i try and add a new Recommendation as part of editing the Review (e.g check another box), nothing is happening - and i know why...

I use the "stub technique" to update my entities - e.g i create a entity with the same key, attach it to the graph, then do ApplyCurrentValues. But this only works for scalar properties, not for navigational properties.

I found this StackOverflow question which looks good, but i am trying to work out how to get this to work with POCO's/Repository (and ASP.NET MVC - detached context).

As i'm using POCO's, review.Recommendations is an ICollection<Recommendation>, so i can't do review.Recommendations.Attach. I'm not using Self-Tracking Entities either, so i need to manually work with the graph/change tracking - which hasn't been a problem until now.

So you can visualize the scenario:

Review:

  • Recommendations (ICollection<Recommendation>):
    • RecommendationOne (Recommendation)
    • RecommendationTwo (Recommendation)

If im on the edit view, two of the checkboxes are already checked. The third one (representing RecommendationThree) is unchecked.

But if i check that box, the above model becomes:

Review:

  • Recommendations (ICollection<Recommendation>):
    • RecommendationOne (Recommendation)
    • RecommendationTwo (Recommendation)
    • RecommendationThree (Recommendation)

And so i need to attach RecommendationThree to the graph as a new entity.

Do i need hidden fields to compare the posted data the existing entity? Or should i store the entity in TempData and compare that to the posted entity?

EDIT

To avoid confusion, here is the full app stack call:

ReviewController

[HttpPost]
public ActionResult Edit(Review review)
{
   _service.Update(review); // UserContentService
   _unitOfWork.Commit();
}

UserContentService

public void Update<TPost>(TPost post) where TPost : Post, new()
{
   _repository.Update(post); // GenericRepository<Post>
}

GenericRepository - used as GenericRepository<Post>

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

So, the Update (or Add or Delete) Repository methods needs to be called for each recommendation, depending it's new/modified/deleted.

解决方案

Perhaps I need more context but whats wrong with:

recommendations.Add(newRecomendation)

?

In reply to comment:

Ok so whats wrong with

SomeServiceOrRepository.AddNewRecommendation( newRecommendation )

or

SomeServiceOrRepository.AddNewRecommendation( int parentId, newRecommendation )

Last Sentence? You mean the two questions?

This shouldn't be hard at all.

To summarize my answer I think you are doing things "the hard way" and really should focus on posting form values that correspond to the CRUD action your trying to accomplish.

If a new entity could come in at the same time as your edited entities you should really prefix them differently so the model binder can pick up on it. Even if you have multiple new items you can use the same [0] syntax just prefix the "name" field with New or something.

A lot of times in this scenario you can't rely on Entity Frameworks graph features because removing an entity from a collection never means it should be set for deletion.

If the form is immutable you could also try using the generized attach function off of ObjectSet:

theContect.ObjectSet<Review>().Attach( review )

Tons of ways out of this. Maybe you could post your controller and view code?

这篇关于ASP.NET MVC / EF4 / POCO / Repository - 如何更新关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆