c# - ObjectContext 已被 EnsureConnection() 在连续查询中抛出(未使用导航属性且未使用())

标签 c# linq entity-framework ef-code-first

EF 在没有任何进一步通知的情况下以某种方式在两个查询之间处理 ObjectContext,但显然不是随机的,也不是由于超时。

我添加了 using,因此该示例是自包含的,但它与整个应用程序中使用的 DbContext 的作用相同。

using (MyDbContext db = new MyDbContext ())
{
  //I am sure these are unique
  Employee emp = db.Employees.Single(e => e.FirstName == "Bob" && e.LastName == "Morane");
  Node node = db.Nodes.Single(n => n.ShortName == "stuff"); //Here the request throws
  // "ObjectContext instance has been disposed and can no longer be used for operations that require a connection"
}

请注意 db 尚未通过 using 处理,因此这是不可能的。 .First().Where().Single/First() 也会发生错误。

反转两个请求并不能解决问题:

using (MyDbContext db = new MyDbContext ())
{
  Node node = db.Nodes.Single(n => n.ShortName == "stuff");
  Employee emp = db.Employees.Single(e => e.FirstName == "Bob" && e.LastName == "Morane"); //Here the request throws
  // "ObjectContext instance has been disposed and can no longer be used for operations that require a connection"
}

我也不使用 Employee 的任何导航属性,这并不能解决问题:

using (MyDbContext db = new MyDbContext ())
{
  // According to every post I've found this "should fix the objectcontext disposed error"
  db.Configuration.ProxyCreationEnabled = false;
  db.Configuration.LazyLoadingEnabled = false;

  Employee emp = db.Employees.Single(e => e.FirstName == "Bob" && e.LastName == "Morane");
  Node node = db.Nodes.Single(n => n.ShortName == "stuff"); //But it doesn't: same error here
}

我注意到这个问题不会出现在 WebSite 项目中,而只会出现在 UnitTests 项目中。我已经为两者设置了相同的 connectionString(除了 db 名称),但这也没有做任何事情。

更糟的是:

using (MyDbContext db = new MyDbContext ())
{
  Node node = db.Nodes.Single(n => n.ShortName == "stuff");
  Employee emp = db.Employees.Single(e => e.FirstName == "Bob" && e.LastName == "Morane"); // boom
  node.Should().NotBeNull();
}

using (MyDbContext db = new MyDbContext ())
{
  Node node = db.Nodes.Single(n => n.ShortName == "stuff");
  node.Should().NotBeNull();
  Employee emp = db.Employees.Single(e => e.FirstName == "Bob" && e.LastName == "Morane"); // no boom
}

超时设置为 20000,MultipleActiveResultSets 设置为 true

目前我发现的唯一解决方法是在尝试 .Single() 之前在整个 DbSet 上调用 .ToList():

using (MyDbContext db = new MyDbContext ())
{
  Employee emp = db.Employees.Single(e => e.FirstName == "Bob" && e.LastName == "Morane");
  Node node = db.Nodes.ToList().Single(n => n.ShortName == "stuff"); //Works
}

但是这是 Not Acceptable ,因为操作很频繁,我预计DbSet会很大,所以这将花费很多时间。

最佳答案

好吧,正如我们(经过 Eregrith 的更多努力)发现的那样,正是 EF 在将上下文发送到测试初始化​​程序之前对上下文进行了操作,因此它的运行出乎意料;通过实现基本的创建/种子/删除而不是初始化程序,异常消失了。 (在我看来,它仍然需要对那里实际发生的事情进行更详细的调查=])

测试初始值设定项是这样调用的:

System.Data.Entity.Database.SetInitializer<MyDbContext>(new DatabaseTestInitializer());

数据库测试初始化​​器:

public class DatabaseTestInitializer : DropCreateDatabaseAlways<MyDbContext>
{
    protected override void Seed(MyDbContext context)
    {
        SeederHelper.Seed(context);
    }
}

删除对 SetInitializer<> 的调用解决了问题。

在基类单元测试中:

[SetUp]
protected virtual void Initialize()
{

  ContainerBuilder builder = new ContainerBuilder();
  this.RegisterTypes(builder);
  this.Container = builder.Build();

  //Removed: System.Data.Entity.Database.SetInitializer<MyDbContext>(new DatabaseTestInitializer());
  this.Db = Container.Resolve<MyDbContext>();
  this.Db.Should().NotBeNull();

  //Below: code added
  this.Db.Database.Delete();
  this.Db.Database.Create();
  SeederHelper.Seed(this.Db);
}

关于c# - ObjectContext 已被 EnsureConnection() 在连续查询中抛出(未使用导航属性且未使用()),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19292602/

相关文章:

c# - 处理 COM 互操作中的访问冲突

C# 算法重构将数组分成 3 部分?

c# - 在 List<string> 中,如何使用 Contains() 方法并检查值是否为空

php - 使用实体管理器从表中选择列的最大值的最简单、最简单的方法是什么?

c# - Entity Framework 6 : Trim does not work properly

c# - 如何拆分数组列表?

c# - 将部分 viewModel 发布到发布操作方法

c# - 在 C# 和 mysql 中制作相同的 sha512

asp.net-mvc - 添加默认的 SelectListItem

asp.net - 使用内存对 .ToListAsync() 进行单元测试