实体框架”;不删除地分离”;用于过滤

本文关键字:分离 用于 过滤 框架 实体 删除 | 更新日期: 2023-09-27 18:21:53

我在实体框架和过滤架构方面遇到了问题。

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

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

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

有没有一种方法可以过滤这些实体对象,这样我就可以使用包含order1、orderline1和orderline3但不包含orderline2的对象图,而以后不会出现问题?因为如果我从entitycollection中删除orderline2,我稍后会出现并发错误(或删除的实体,这是我不想要的)

我希望问题是清楚的,我知道可能有其他方法(迭代而不在orderline2上执行更新,所以它保持不变,不做任何更改),但架构的构建方式现在不允许我这么做。

如果我可以说"不要再跟踪对orderline2的任何更改,忽略我对这个特定对象和子对象所做的任何更改",这样我就可以从集合中删除它并继续前进,这将是完美的

谢谢!

实体框架”;不删除地分离”;用于过滤

正如您已经描述的那样,您可以采用多种方式:

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

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,它被传递到几个方法中,并且您获得了某些实体的更新请求。然后,分离那些更新请求不需要的实体也可以是一种选择。也许MSDN上的这个主题可以帮助你做出决定。之后,您可能会再次附加分离的对象,以便后续的"客户端"调用可能需要它们。但这取决于您如何管理ObjectContext。

您是通过多次"客户端"调用保持ObjectContext"活动",还是针对特定的客户端调用反复实例化它。我还没有完全弄清楚情况。。。