【问题标题】:The context cannot be used while the model is being created创建模型时无法使用上下文
【发布时间】:2012-03-17 12:49:15
【问题描述】:

在我的应用程序中,我收到以下错误:

在创建模型时不能使用上下文。

我不确定这意味着什么。我已经正常完成了所有工作,通常它可以工作,但对于这个它不是。以下是我的代码:

App.config:

 <connectionStrings>
    <add name="DatabaseContext" connectionString="Data Source=./SQLEXPRESS;Initial Catalog=ProjectCode;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
 </connectionStrings>

Products.cs:

class Products
{
    public int ProductID { get; set; }
    public string ProductName { get; set; }
}

DatabaseContext.cs:

class DatabaseContext : DbContext
{
    public DbSet<Products> Products { get; set; }
}

程序.cs:

DatabaseContext context = new DatabaseContext();

try
{
   var products = context.Products.ToList();

   foreach (var item in products)
   {
      Console.WriteLine(item.ProductID + " : " + item.ProductName);
   }
      Console.ReadLine();
}

失败的线路是var products = context.Products.ToList();

任何想法可能导致这种情况?我在我的数据库中设置了 2 个产品,所以它应该输出它们。

编辑

这是我的整个 App.config 文件:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </configSections>
  <connectionStrings>
    <add name="DatabaseContext" connectionString="Data Source=./SQLEXPRESS;Initial Catalog=ProjectCode;Integrated Security=SSPI;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="Data Source=.\SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

【问题讨论】:

  • 这是您应用程序中唯一的代码吗?没有数据库初始化程序?没有并发调用(多线程、多应用实例等)?
  • 是的,这是唯一使用数据库的代码,没有并发调用,它现在只是一个基本的控制台应用程序
  • 你解决了吗?我也有同样的问题...
  • 是的,检查我标记为解决方案的答案。就我而言,我使用的是正斜杠 (/) 而不是反斜杠 (\)
  • 我收到同样的错误只是因为我的 sql server 服务处于停止状态。

标签: c# entity-framework


【解决方案1】:

在连接字符串下的 App.Config 文件中,您有一个正斜杠 (./SQLEXPRESS)。将其更改为反斜杠 .\SQLEXPRESS,如下所示:

<add name="DatabaseContext" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=ProjectCode;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />

【讨论】:

  • @TomW 我认为这会有所帮助,因为任何导致错误的连接字符串问题都可能引发 OP 询问的错误。我不小心用我的 MySQL 连接字符串替换了 DefaultConnection 连接字符串(新的 MVC Web 应用程序附带),我收到了同样的错误。即使我没有使用它,代码仍然引用它。
  • 我缺少连接字符串导致此错误。
  • 我的连接字符串有问题。
  • @TomW 获取连接字符串时,如果您有正斜杠,则检索它的代码将期望它被转义。如果你只有一个,它将否定整个字符串的其余部分。
【解决方案2】:

我过去遇到过这个问题,通常是由于没有使用最新版本 + 引用问题。

尝试从 NuGet 为您的所有项目获取最新的 EF 版本,看看错误是否消失:
http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-released.aspx

更新
此错误的另一个原因可能是当您第一次创建上下文并因此导致创建模型时,您在单独的线程上创建了另一个上下文。模型创建完成后,您必须等待创建其他上下文实例。

【讨论】:

  • 我用的是EF的4.3.1版本,是最新版本
  • @BiffBaffBoff 此错误的另一个原因是多线程。您是否从多个线程访问上下文?因为模型是在DatabaseContext第一次实例化时创建的,所以当你尝试创建DatabaseContext的另一个实例时你也会收到这个错误,你必须等待模型创建准备好
  • 我没有在我的应用程序的其他地方调用上下文,我只是创建了这个小型控制台应用程序来测试 EF 及其工作原理。
  • @ntziolis 请添加您的评论作为答案,这是我的问题!
【解决方案3】:

我能够通过添加解决此问题

MultipleActiveResultSets=true

到我的 EF 连接字符串。

我通过添加这个多线程连接参数来修复它。

【讨论】:

  • 这解决了我的问题。我有两个由 WebAPI 创建的线程同时查询上下文。通过打开 MARS,它完全解决了这个问题。如果您使用的是多线程环境,例如 WebAPI,请考虑使用此解决方案。
  • 这是个坏建议。 MARS 是一种隐藏潜在问题的解决方法。
  • 很遗憾,我在 6.1.3 中遇到了这个问题,我已经启用了这个功能。
  • @shortstuffsushi 实际上,根本问题是 DBContext 不是线程安全的,因此您不应该创建它的多个实例。通过打开它,您现在可以执行此操作 - 您只是冒着尝试打开数据库连接时线程被锁定的风险,仅此而已。
【解决方案4】:

我也遇到了这个错误,但能够通过在每个线程内声明一个局部变量上下文而不是使用我在全局声明的那个来解决它。

    Parallel.ForEach(myList, l=>
    {
        MyContext _db = new MyContext();
        // do some stuff....
        _db.Model.Add(....);
        _db.SaveChanges();

    });

确保您还如上所述在连接字符串中设置了 MultipleActiveResultSets=true。

【讨论】:

  • 谢谢,这解决了我的问题。由于实体框架不是线程安全的。
【解决方案5】:

在我的例子中,我使用的是 Code First,我忘记更新数据库以获取最后的更改。上下文和数据库必须相同。如果没有,请在包管理器中输入以下代码;

Update-Database

【讨论】:

    【解决方案6】:

    通过以下方式解决:

    我在我的应用程序中遇到了同样的问题,并使用以下方法解决了。

    1. 验证您的模型名称和表名称,它们应该匹配。

    2. 模型中使用的数据类型和列名与数据库表列名/数据类型应匹配。

    3. 在您的 Context 类中使用以下代码

      Public class MVCRepositoryContext : DbContext 
      {
          static MVCRepositoryContext()
          {
              Database.SetInitializer < mvcrepositorycontext > (null);
          }
      
          public MVCRepositoryContext():base("MVCRepositoryContext"){ }
      
          public virtual DbSet<customer> Customers { get; set; }
      
          public virtual DbSet<book> Books { get; set; }
      
          public virtual DbSet<author> Authors { get; set; }
      }
      

    【讨论】:

      【解决方案7】:

      我今天也遇到了同样的问题。
      就我而言,重新启动 Visual Studio 解决了这个问题。

      【讨论】:

        【解决方案8】:

        使用数据库目录名称添加 DatabaseContext 构造函数。

        public class DatabaseContext : DbContext {
            public DbSet<Products> Products { get; set; }
        
            public DatabaseContext() : base("ProjectCode") {}
        }
        

        像这样在 app.config 中更改 entityframework 配置。

        <parameter value="Data Source=./SQLEXPRESS;Initial Catalog=ProjectCode;Integrated Security=SSPI;MultipleActiveResultSets=true" />
        

        为 Products 类添加注释。确保您的数据库有一个“Products”表,其中包含两个字段“ProductId”和“ProductName”。

        class Products {
            [Key]
            public int ProductID { get; set; }
            public string ProductName { get; set; }
        }
        

        如果仍然出错,请尝试将您的项目目标框架更改为使用 .net framework 4.0。

        【讨论】:

        • 我不确定这将如何解决它,因为我的类名与连接字符串名称相同?但我已经尝试过了,仍然得到同样的错误
        【解决方案9】:

        我遇到了同样的问题并使用以下代码解决了它:

        Database.SetInitializer<EntitiesName>(null);
        

        【讨论】:

        • 我也面临同样的问题。你能解释一下我应该把上面的代码行放在哪里吗
        • 对于 MVC 项目,放置此代码的最佳位置是 Global.asax 文件中的 Start 函数 protected void Application_Start() { /*here*/ }
        • 这个答案没有任何解释没有任何意义。考虑添加您这样做的原因,以及它是“可接受的”解决方案,还是只是临时解决方法。
        【解决方案10】:

        我有同样的问题。我检查了我的连接字符串并确保 SQL Server 服务正在运行以解决此问题。

        【讨论】:

          【解决方案11】:

          我知道这是一张旧票,但我也可以帮助遇到同样问题的其他人,就我而言,我没有在 app.config 文件的连接字符串中加载上下文:

          例如

          <add name="SalesContext" connectionString="" providerName="System.Data.SqlClient" />
          

          这应该可行。

          您好。

          【讨论】:

            【解决方案12】:

            代码中的一个错误是始终在using 块中使用数据库上下文。数据库上下文不是线程安全的。并且每次请求最好使用一次

            【讨论】:

              【解决方案13】:

              我也遇到了同样的问题...但是,我的问题是我使用的是自定义角色提供程序。这个角色提供者引用了我的上下文,该上下文在应用程序的整个生命周期中保持打开状态。在多个 Web 浏览器尝试同时发出请求之前,这不是问题。

              我的解决方案是在每个重写的方法中的自定义 RoleProvider 中创建一个新上下文,并通过 using 语句进行处理。

              using(var ctx = new Entities())
              {
                  //do stuff                
              }
              

              因此,基本上,如果您遇到此错误,则需要查看堆栈跟踪并查看错误发生在哪个方法/文件上,然后修改有问题的方法/类以每次处理上下文。

              在我的例子中,我使用了 Ninject DI,并在我的自定义角色提供程序和自定义操作过滤器中实现了 DI。为了解决多个线程访问同一上下文的问题,我取消了这些类中的 DI,并直接为每个类创建新的上下文。

              【讨论】:

                【解决方案14】:

                1 - 确保连接字符串有反斜杠而不是正斜杠:

                connectionString="Data Source=.\SQLEXPRESS ....
                

                2 - 将MultipleActiveResultSets=true 添加到连接字符串。

                3 - 导致我的原因是我的 DbContext 类有多个构造函数:

                using System.Data.Entity;
                using System.Data.Entity.Infrastructure;
                using System.Data.Entity.ModelConfiguration.Conventions;
                
                namespace MyProject
                {
                    public partial class Model1 : DbContext
                    {
                        // I had to comment out this one ...
                        //public Model1()
                        //    : base("name=Model1")
                        //{
                        //}
                
                        public Model1(bool enableLazyLoading = true)
                            : base("name=Model1")
                        {
                            //Database.SetInitializer<Model1>(new CreateDatabaseIfNotExists<Model1>());            
                            //this.Configuration.LazyLoadingEnabled = false;
                
                            Database.SetInitializer<Model1>(null);
                            this.Configuration.ProxyCreationEnabled = false;
                
                            ((IObjectContextAdapter)this).ObjectContext.ContextOptions.LazyLoadingEnabled = enableLazyLoading;          
                            ((IObjectContextAdapter)this).ObjectContext.ContextOptions.ProxyCreationEnabled = enableLazyLoading;
                        }
                
                        public virtual DbSet<Product> Products { get; set; }
                        // ...
                        protected override void OnModelCreating(DbModelBuilder modelBuilder)
                        {
                            // ...
                        }
                    }
                }
                

                一旦我注释掉原来的 Model1 构造函数,它就解决了。

                我留下了 2 个版本的延迟加载/Database.SetInitializer 以显示有两种方法可以做到这一点 - 启用或禁用。

                • 如果您使用前 2 行而不使用它,请不要使用接下来的 4 行并删除 bool enableLazyLoading = true
                • 如果您确实使用如图所示的 4 行,请确保将这 2 行注释掉并保留 bool enableLazyLoading = true

                【讨论】:

                  猜你喜欢
                  • 2014-06-11
                  • 1970-01-01
                  • 2016-01-13
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-02-16
                  • 2015-11-14
                  相关资源
                  最近更新 更多