2012-05-04 38 views
0

您好我试图做一个基于使用Linq和实体框架的ID基本更新。我对此很新,但我没看到问题。实体框架LINQ插入命令失败。 MVC3

我的实体类对象在控制器级别声明。

gwwbnEntities db = new gwwbnEntities(); 

该方法捕获查询字符串ID并更新用该ID表示的用户的注册状态。

public ActionResult ConfirmedAccount(int id) 
    { 

     var q = from u in db.user_registration 
       where u.id == id && u.reg_status == null 
       select u; 

     if (q.Any()) 
     { 
      foreach(var item in q){ 

      user_registration user = item; 
      user.reg_status = 202; 
      db.Entry(user).State = EntityState.Modified; 
      db.SaveChanges(); 
      } 

      return View(); 
     } 
     else 
     { 
      return RedirectToAction("RegistrationError"); 
     } 
    } 

任何帮助将不胜感激!再次,所有的工作和填充正确,但上下文object.SaveChanges()方法每次都失败。

谢谢你们!

+5

失败,哪个例外? – user7116

+0

你有没有想过不止一场比赛?如果不是,你为什么使用“foreach”? – BrokenGlass

+0

例外情况是:新事务不被允许,因为会话中还有其他线程正在运行。 异常详细信息:System.Data.SqlClient.SqlException:由于会话中还有其他线程正在运行,因此不允许新的事务。由于易于编码,我只是使用foreach。如果你会建议采取不同的方式,我绝对是耳朵。正如我所说,我对LINQ和实体框架非常陌生。非常感谢你们! – user1345632

回答

3

您看到的异常是因为您有一个开放的数据读取器(foreach),并且您正尝试在SaveChanges()中创建事务处理(EF会为您执行此操作)。在循环外调用SaveChanges。另外:不要将状态设置为修改 - EF将检测到属性已更改,并会自动设置相应的状态。在做任何事之前,你可能想在q上做.ToList()。目前您正在向数据库发送查询(一个用于.Any(),另一个用于获取实体)。如果你做.ToList(),你将只发送一个带有实体的查询,但是.Any()会在列表上被调用,而不是在数据库上调用,所以它会快得多,并且没有数据库访问。另外ToList()强制查询评估,因此您的foreach循环不会保持数据读取器处于打开状态,因为它将在列表中迭代。

+0

要展开此操作,您还可以执行此操作: var q =(从u到db.user_registration 其中u.id == id && u.reg_status == null select u).ToList(); 然后,当您循环播放结果并发出.SaveChanges()调用时,阅读器不会再打开。 –

+0

正如我上面的评论,它也将保存到数据库的旅行......我会将我的评论复制到答案。 – Pawel

+0

这工作非常好!谢谢你的解释! – user1345632