实体框架“无删除分离”进行过滤

时间:2012-01-27 19:24:17

标签: c# .net entity-framework entity-framework-4

我遇到了实体框架和过滤架构的问题。

假设我有几个相关的实体,我想根据过滤器对它们进行一些更改。

所以,例如我有Orders和Orderlines(举一个简单的例子) 我有order1,DB中有orderline1,orderline2,orderline3关系

然后我收到order1的更新请求,但仅针对orderline1和orderline3 我使用实体框架从db获取数据,实体框架检索订单及其行的对象图。

有没有办法过滤这些实体对象,以便我可以使用包含order1和orderline1以及orderline3的对象图,但是不能在以后没有出现问题的orderline2? 因为如果我从entitycollection中删除orderline2,我后来会遇到并发错误(或删除的实体,这是我不想要的)

我希望这个问题很明确,我知道可能有其他方法(迭代和不在orderline2上执行更新,所以它保持不变并且没有进行任何更改)但是架构的制作方式并不让我现在就这样做。

如果我可以说“不跟踪对orderline2的任何更改,只要忽略我对此特定对象和后代所做的任何更改,只需将其保留在DB中”,这样我就可以删除它来自收藏和前进,这是完美的

谢谢!

1 个答案:

答案 0 :(得分:0)

你可以采用多种方式,如你自己所描述的那样:

  1. 迭代所有订单行,只修改那些需要修改的订单(但这不是你所说的选项)
  2. 您所描述的替代方案是专门不跟踪orderline2的更改,这在“正常”EF情况下是不可能的,其中ObjectStateManager负责更改跟踪(据我所知)。在具有自我跟踪实体的情况下,它更容易,因为每个STE都有自己独特的ChangeTracker,可以轻松关闭。
  3. 但最简单的选择是排除您不想在“select”语句中修改的订单行或检索实体。类似的东西:

  4. private void ModifyOrderLines(int orderID, List<int> orderlineIds)
    {
      using(Context context = new Context)
      {
        List<OrderLines> orderlines = 
        context.OrderLines.
        Where(orderLine => orderLine.OrderID == orderID && orderlineIDS.Contains(orderLine.ID))   
      } 
    }
    

    假设您已设置干净的外键关系,这些关系已转换为EF中的导航属性。因此,您要做的是获取属于某个订单的OrderLines列表,并且具有需要修改的OrderLines列表中的ID。

    然后您更改订单行并将更改应用于上下文并调用SaveChanges。这只是你如何做事的基本方式。我不知道你的确切设置,但我希望这有帮助。

    修改

    根据你的评论,我应该采用简单的方法,并按照你已经提出的方式编写一个循环。为什么不?我不认为有很多替代方案,如果有,那么它们会使事情变得过于复杂。

    这样的事情可能会奏效:

    ObjectContext.OrderLines.ForEach(o => if(orderlineIds.Contains(o.ID) {o.SomeProperty = SomeValue}));
    

    或者您可以自己编写循环。

    <强> EDIT2

    您已经提到从帖子标题中的ObjectContext中分离。那为什么不那样走呢?您告诉您无法控制您获得的ObjectContext,它将传递给多个方法,并且您获得某些实体的更新请求。然后,分离更新请求不需要的实体也是一种选择。也许this topic on MSDN可能会帮助您做出决定。之后,您可能会再次附加分离的对象,因为后续的“客户端”调用可能需要这些对象。但这取决于您如何管理ObjectContext。

    您是否将ObjectContext保持为“活动”多个“客户端”调用,或者您是否为特定客户端调用反复实例化它。我不清楚这种情况......