【问题标题】:EF4 Not Seeing Changes on context before Save ChangesEF4 在保存更改之前看不到上下文的更改
【发布时间】:2012-12-13 16:47:10
【问题描述】:

您好,我在 EF4 上下文中使用工作单元模式。

上下文通过几个方法传递,所有方法都在它上面工作,然后在完成后我调用保存更改。

当我稍后对对象的状态进行检查时,它是旧值而不是新值。但是,如果我此时调用保存更改,我希望在上下文中看到的状态将保存到数据库中。

本质上调用堆栈是

Context ctx;

UpdateItems(ctx);
CheckItemsValid(ctx);
DoSomehtingElse(ctx); //Saving changes here.

现在CheckItemsValid 失败了,因为它看不到UpdateItems 中所做的更改,但它是相同的上下文。

如果我将整个内容包装在 TransactionScope 中并在调用检查项之前调用 SaveChanges,那么一切正常,但看起来有点像大锤。

我在更新项目方法中更新项目后尝试了以下方法。

ApplyCurrentValues();
Refresh(ClientWins);
AcceptAllChanges();

以前有没有人见过这个问题,还是我必须处理整个事情并调用保存更改流程?

    using (EntitiesContext ctx = EntityFactory.GetEntitiesContext())
        {

            Repairs.RepairManager repman = new Repairs.RepairManager();

            repman.SetAllRepairsOfTypeToComplete(vehicle.VehicleId, RepairTypes.BodyShop, vehicle.SiteVisitId.Value, technicianId, ctx);


            SchemeManager sm = new SchemeManager();
            result = sm.ProcessVehicle(AutoMapper.Mapper.Map<EFVehicle, AbstractVehicle>(ctx.EFVehicles.Single(p => p.VehicleID == vehicle.VehicleId), new Vehicle()), ref intrules, userId, ctx, false);


            if (result == true)
            {
                ctx.SaveChanges();         
            }

流程车辆调用检查 SetAllRepairsOfTypeToComplete 是否成功的基础

将所有修复设置为完成只需将上下文 ctx.EFRepairs 上的修复列表中的某个位从 true 更新为 false。

  var cancelledrepairs = ((EntitiesContext)Context).EFRepairs.Where(p => p.VehicleID == vehicle.VehicleId && p.VehicleSiteVisitID == vehicle.SiteVisitId
            && p.RepairTypeID == (int)RepairTypes.BodyShop && p.RepairStatusID == (int)RepairStatusEnum.Cancelled).Count();

        var completedMechrepairs = ((EntitiesContext)Context).EFRepairs.Where(p => p.VehicleID == vehicle.VehicleId && p.VehicleSiteVisitID == vehicle.SiteVisitId
            && p.RepairTypeID == (int)RepairTypes.BodyShop && p.RepairStatusID == (int)RepairStatusEnum.Completed).Count();

        var CurrentMechanicalRepairs = ((EntitiesContext)Context).EFRepairs.Where(p=> p.VehicleID == vehicle.VehicleId && p.VehicleSiteVisitID == vehicle.SiteVisitId
            && p.RepairTypeID == (int)RepairTypes.BodyShop).Count();

        if ((completedMechrepairs + cancelledrepairs) == CurrentMechanicalRepairs)
            return true;
        else
        {
            failureMessage = "Not all mechanical repairs for this vehicle are complete";
            return false;
        }

completedMechrepairsCount 始终为 0,即使它们在同一上下文中的 SetAllRepairsOfTypeToComplete 中进行了更新。

【问题讨论】:

  • 你能发布一些代码让我们继续吗?
  • @jmrnet 已更新以显示相关过程。
  • 好的。 ProcessVehicle 中的检查如何检查“成功”?你能告诉我那个代码吗?
  • @jmrnet 添加了检查代码忽略了机械消息它只是复制和粘贴尚未修复的内容:)

标签: c# entity-framework c#-4.0 orm


【解决方案1】:

这原则上应该可行。我什至创建了一个模仿这种行为的本地测试,它对我有用。我认为最可能的原因是:(任何/全部)

1) 您的 SetAllRepairsOfTypeToComplete 方法没有更新您认为的对象。

-或-

2) 您获取 completedMechrepairs 计数的查询没有选择正确的对象。

尝试在您的 EFRepair 对象具有唯一 ID 的情况下进行一些调试,您可以使用该 ID 查看它是否已更新。然后从您的 completedMechrepairs 检查中获取一个列表,并查看具有该 ID 的 EFRepair 对象是否在列表中。

【讨论】:

  • 我今天来看看。我追踪了电话,上下文似乎是同一个,但现在我醒了,我会再看一遍并报告:)
  • 发现发生了什么,但不知道为什么。 cancelledrepairs 和 completedmechrepairs 正在调用 db currenmechrepairs 不会命中 db 并使用 statemanager 中的对象列表,这是非常奇怪的行为!
  • 你是说现在它在你完成的Mechrepairs计数中击中数据库而不是状态管理器?
  • 是的,我所做的一切似乎都无法阻止已完成和已取消对数据库的访问。它与上下文的投射无关。我在转换上下文之前复制了代码,结果是其他 2 个查询的 2 个数据库命中相同。
  • 啊!看看这篇文章。我想你会在那里找到你的答案。 stackoverflow.com/questions/6990618/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 1970-01-01
  • 2022-01-23
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 2011-04-07
相关资源
最近更新 更多