【问题标题】:SaveChangesAsync not updating value in database tableSaveChangesAsync 不更新数据库表中的值
【发布时间】:2015-08-04 00:18:32
【问题描述】:

这是我的表格:统计数据

Id,Depth,RefreshCounter

样本记录:

Id    Depth      RefreshCounter
 1     1           1
 2     1           0
 3     1           0
 4     1           0

现在我需要做的是,每当我刷新页面时,我需要在深度为 1 的数据库表中将此 refreshcounter 值增加 1

我在加载我的视图页面时这样调用这个方法:

@Html.Action("IncrementRefreshcounter", "Statistics", new { id = 1})  //for eg:1,2,3,4

这是我的代码:

    [ChildActionOnly]
    public ActionResult IncrementRefreshcounter(int id)
       {
         using ( var context = new MyDBContext())
         {
//at each page refresh i would be passing different id to my controller from view.for eg 1,2,3,4
         var data=context.Statistics.where(x=>x.Depth==1 && r.Id==id).FirstorDefualt();
             context.RefreshCounter++;//Increment here RefreshCounter.
             context.SaveChangesAsync();
             return PartialView("xxx")
            }
        }

当我的 View Loads.Problem 是当我第一次运行我的应用程序并调用此方法时,我调用此方法,它成功地将 RefreshCounter 更新了 1,但之后每当我刷新我的页面并调用此方法时,它从未更新 RefreshCounter Depth=1 的记录。

在我的示例记录中,您可以看到深度为 1 的 Id 1 具有值为 1 的刷新计数器,因为这是我第一次运行我的应用程序并且它已成功更新该值,但之后它不再更新任何值例如:Id 2 Depth 1

RefreshCounter 只增加 1 次,但之后它不再增加该变量。

谁能告诉我问题是什么SaveChangesAsync??

【问题讨论】:

  • 你想用Depth==1更新其他记录还是只更新第一条记录?
  • @MehrdadKamelzadeh:其他记录也不仅仅是 depth==1 和 id==1.others 记录,因为在每次刷新时我都会将不同的 id 传递给我的控制器
  • 那你为什么写where(x=>x.Depth==1).FirstorDefualt() ??它只返回条件找到的第一条记录。我的意思是它会找到他们Depth==1 的所有记录,然后它只返回第一个!

标签: c# asp.net-mvc entity-framework async-await


【解决方案1】:

您必须等待保存,否则该方法将继续,并且您的上下文将超出范围,然后再保存更改。您也必须使方法异步。

public **async** Task<ActionResult> IncrementRefreshcounter(int id)
       {
         using ( var context = new MyDBContext())
         {
//at each page refresh i would be passing different id to my controller from view.for eg 1,2,3,4
         var data=context.Statistics.where(x=>x.Depth==1 && r.Id==id).FirstorDefualt();
             context.RefreshCounter++;//Increment here RefreshCounter.
             await context.SaveChangesAsync();
            }
        }

【讨论】:

  • 喜欢怎么样,因为我的方法是actionresult。你能发布任何示例吗?
  • 查看我的更新答案。您需要像通常这样的视图或重定向一样返回操作结果。
  • 请查看我更新的问题,我不了解您所写的内容,但出现 thsi 错误:HttpServerUtility.Execute 在等待异步操作完成时被阻塞
  • 在进入异步世界之前(所有涉及的方法必须在链上异步),所以将代码恢复为同步:从方法中删除异步任务,然后等待,调用同步上下文.SaveChanges 方法。我在之前的评论中提到了您的代码中未使用“数据”的可能错误。解决此问题后,您可以尝试异步调用。
  • 不幸的是,您不能从 @Html.Action() 调用异步方法 - 它不受支持:aspnetwebstack.codeplex.com/workitem/601 - 我会考虑创建一个帮助器类来增加计数器,并从操作中调用它加载您使用 @Html.Action() 的视图。
【解决方案2】:

试试这个:

   public async Task<ActionResult> IncrementRefreshcounter(int id)
   {
     using ( var context = new MyDBContext())
     {
//at each page refresh i would be passing different id to my controller from view.for eg 1,2,3,4
     var data=context.Statistics.where(x=>x.Depth==1 && r.Id==id).FirstorDefualt();
         context.RefreshCounter++;//Increment here RefreshCounter.
         await context.SaveChangesAsync();
        }
    }

SaveChanges 将在当前线程上执行并在等待查询完成时阻塞线程,从而阻止线程做其他工作,即使线程只是坐在那里等待 IO。

SaveChangesAsync 将启动 IO 命令,然后在 IO 进行时释放请求线程以执行其他工作。一旦 IO 完成,该方法的其余部分将在捕获的同步上下文中执行。

因此,对于使用异步 API 进行 IO 绑定工作的 Web 服务器,您可以使用更少的线程处理更多请求,从而使您的应用程序更具可扩展性,并且它将使用更少的内存,并且每个线程默认具有 1MB 的堆栈空间.

同步工作就像SaveChanges 方法。在保存更改之前,方法调用不会返回。

异步工作就像SaveChangesAsync,方法调用启动操作并返回一个Task,以便您可以跟踪它。一段时间后,更改会保存在后台,同时您可以使用返回的Task 来跟踪操作。

【讨论】:

  • 请查看我更新的问题,我不了解您所写的内容,但出现 thsi 错误:HttpServerUtility.Execute 在等待异步操作完成时被阻塞
  • HttpServerUtility.Execute 在等待异步操作完成时被阻塞
  • 另外你使用的是什么版本的 ASP?
  • 查看这篇文章,了解使用 MVC codeclimber.net.nz/archive/2012/01/09/…987654321@ 进行异步调用时的各种替代方案
  • 不支持异步子操作的那个?这是真的,但是如果您的控制器是 AsyncController,那么应该有一种方法可以使操作异步,如我发布的博客文章的链接中所示
猜你喜欢
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
  • 2017-09-04
  • 1970-01-01
  • 1970-01-01
  • 2018-10-15
相关资源
最近更新 更多