NpGsql EntityFramework 6 - “操作已经在进行中”
Posted
技术标签:
【中文标题】NpGsql EntityFramework 6 - “操作已经在进行中”【英文标题】:NpGsql EntityFramework 6 - "An operation is already in progress" 【发布时间】: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 【参考方案1】:我已经成功地在 linq 查询之后使用ToList<T>
解决了这个问题,如下所示:
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<T>
可以解决问题。 .Net 将 linq 语句的执行推迟到最后一刻,这可能是问题的一部分。我试图在 foreach 中使用 q 但没有成功。
【讨论】:
【参考方案2】:问题是由GetUsers()
方法的返回类型引起的。由于是IEnumerable<User>
,LINQ-to-SQL 会将结果加载到内存中(逐行),随后的Where
、OrderBy
、Select
、Count
等调用将在内存中执行。当评估Where
条件时,原始结果集仍在迭代,但关系User.Role
需要在数据库上解决(这就是“操作已在进行中”错误消息的来源)。
如果返回类型更改为IQueryable<User>
,则在调用Count
方法之前不会执行查询,而且整个查询将被转换为只返回计数而不加载任何@的SQL 987654332@ 记录到内存中。
另请参阅此相关问题/答案:Returning IEnumerable<T> vs. IQueryable<T>
建议在查询中调用ToList()
的答案会将整个结果集加载到内存中,这会使您的错误消失,但根据结果集的大小,效率也可能非常低。
【讨论】:
以上是关于NpGsql EntityFramework 6 - “操作已经在进行中”的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework 5.0 PostgreSQL (Npgsql) 默认连接工厂
Entity Freamwork 6连接PostgreSql数据库
npgsql 和 Entity Framework 代码第一次设置问题