【问题标题】:Entity Query Not Updating in For Each Correctly实体查询未正确更新 For Each
【发布时间】:2011-08-02 03:14:00
【问题描述】:

我有以下代码:

  ' Now retabulate the current occupancy.
        For Each row In assignments
            Try
                Dim assignment As Integer = row.room
                Dim student_id As String = row.id
                Dim update_occupancy = (From p In dbContext.Beds _
                                        Where p.occupant = 0 _
                                        Where p.room = assignment _
                                        Select p).FirstOrDefault
                update_occupancy.occupant = student_id

            Catch ex As Exception

            End Try

        Next
        dbContext.SaveChanges()

在这一部分中,我正在遍历当前的作业,当床未被占用 (=0) 并且房间等于当前学生时,我将学生插入该房间。

问题是 update_occupancy 似乎总是保持不变。比如我可能有四张床(ID 101、102、103、104),第一次学生应该分配到101,下一个学生应该分配到102,下一个学生应该分配到103,以此类推。但它只是一遍又一遍地覆盖第一个。我不能在 For Each 中放置一个 dbContext.SaveChanges(),它会中断。想法?

【问题讨论】:

  • “我不能将 dbContext.SaveChanges() 放在 For Each 中,它会中断”
  • 我愿意,但我已经用 Try/Catch 将它放在那里,但它仍然只是覆盖!
  • 有什么异常?放入 Try/Catch 块没有帮助,它只会隐藏错误并不能解决它。
  • 如果我删除 Try..Catch 我得到的 InnerException 是:"{"新事务是不允许的,因为会话中还有其他线程在运行。"}"
  • 我用这个来纠正这个问题:weblogs.asp.net/jimjackson/archive/2010/07/08/…

标签: asp.net vb.net entity-framework entity-framework-4 linq-to-entities


【解决方案1】:

这是一个明显的问题。您正在向数据库询问没有占用者的记录并分配新占用者但不保存更改,您是在循环中执行此操作,因此查询必须始终返回同一行。

只有当assignments 是查询的枚举结果时才会发生您的异常。如果您想避免该异常,只需在查询中调用 ToList。

我仍然会考虑算法并尝试预先加载床。这需要一个查询来获得分配和一个查询 + 每张床的一个更新。如果您的分配返回 1.000 行,您将不得不对床位进行 1.000 次查询。您不会避免 1.000 次更新,因为 EF 不支持命令批处理。在您的算法中还有关于什么是事务的决定。是更新单人床还是处理所有加载的assignments?根据这个决定,您还可以考虑您的算法。

顺便说一句。如果assignments 是一个查询,它很可能会被重写为一些与床的连接,这样您就不需要在循环中进行子查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多