【问题标题】:NpGsql EntityFramework 6 - "An operation is already in progress"NpGsql EntityFramework 6 - “操作已经在进行中”
【发布时间】:2016-04-05 07:06:06
【问题描述】:

我正在开发一个使用 NpGsql EntityFramework 6 连接到 PostgreSQL 数据库的项目。当我尝试在 GetAdminUsersCount 中执行查询时,我得到了问题标题中的异常:

public class GenieRepository : IDisposable
{
    GenieDbContext db = new GenieDbContext();
    public IEnumerable<User> GetUsers()
    {
        return db.Users;
    }   
}

public int GetAdminUsersCount()
{
    return repo.GetUsers().Where(u => u.Role.RoleName == "Administrator").Count();
}

此错误的原因是什么以及如何解决?

【问题讨论】:

  • 旁注:PostGre Sql:哦,嗯???使用Postgres or PostgreSQL
  • 你用的是哪个版本的NpgSql?如果你部署在 mono 上是哪个版本?
  • NpgSql 3.0.4.0,实体框架 6.0
  • 在 Mono 3.x 中发现了类似的问题,但在升级到 4.x 后得到了解决。尝试降级到 NpgSql 2.2.7
  • 看到同样的问题,EF 6.1.3,NpgSql 3.0.5

标签: c# entity-framework postgresql npgsql


【解决方案1】:

我已经成功地在 linq 查询之后使用ToList&lt;T&gt; 解决了这个问题,如下所示:

using (ElisContext db = new ElisContext()) {
    var q = from a in db.aktie select a;
    List<aktie> akties = q.ToList<aktie>();
    foreach (aktie a in akties) {
        Console.WriteLine("aktie: id {0}, name {1}, market name {2}"
                 , a.id, a.name, a.marked.name);
    }
}

注意q.ToList&lt;T&gt; 可以解决问题。 .Net 将 linq 语句的执行推迟到最后一刻,这可能是问题的一部分。我试图在 foreach 中使用 q 但没有成功。

【讨论】:

    【解决方案2】:

    问题是由GetUsers() 方法的返回类型引起的。由于是IEnumerable&lt;User&gt;,LINQ-to-SQL 会将结果加载到内存中(逐行),随后的WhereOrderBySelectCount 等调用将在内存中执行。当评估Where 条件时,原始结果集仍在迭代,但关系User.Role 需要在数据库上解决(这就是“操作已在进行中”错误消息的来源)。

    如果返回类型更改为IQueryable&lt;User&gt;,则在调用Count方法之前不会执行查询,而且整个查询将被转换为只返回计数而不加载任何@的SQL 987654332@ 记录到内存中。

    另请参阅此相关问题/答案:Returning IEnumerable<T> vs. IQueryable<T>

    建议在查询中调用ToList() 的答案会将整个结果集加载到内存中,这会使您的错误消失,但根据结果集的大小,效率也可能非常低。

    【讨论】:

      猜你喜欢
      • 2017-01-28
      • 2016-09-27
      • 2021-11-25
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多