![](/img/trans.png)
[英]Entity Framework 6 exception: “The context cannot be used while the model is being created”
[英]Entity Framework - The context cannot be used while the model is being created
我正在尝试创建一个控制台应用程序,我在其中尝试使用 Entity Framework 动态创建数据库和表来存储数据。 但是,当我尝试将数据添加到我的DbSet
。 我收到以下错误。
EntityFramework.dll 中发生类型为“System.InvalidOperationException”的未处理异常
附加信息:创建模型时不能使用上下文。 如果在 OnModelCreating 方法中使用上下文,或者多个线程同时访问相同的上下文实例,则可能会引发此异常。 请注意,不保证 DbContext 和相关类的实例成员是线程安全的。
我参考了其他有类似错误的帖子,但没有一个解决方案有效。 这是一个单线程应用程序。
错误发生在行
this.context.Environments.Add(entity)
数据源文件
public class DataSource
{
private static DataSource instance;
public DataSource()
{
this.context = new CounterContext();
}
public static DataSource Instance
{
get
{
return instance ?? (instance = new DataSource());
}
}
private CounterContext context;
public void AddCockpitEnvironmentDetails(IList<Environment> environmentList)
{
foreach (var entity in environmentList)
{
this.context.Environments.Add(entity);
}
this.context.SaveChanges();
}
...
}
我的背景:
public class CounterContext : DbContext
{
public CounterContext()
: base("name=CounterDbString")
{
Database.SetInitializer<CounterContext>(new CreateDatabaseIfNotExists<CounterContext>());
}
public DbSet<CounterData> CounterDetails { get; set; }
public DbSet<Environment> Environments { get; set; }
}
型号
public class Environment
{
[Key]
public Guid Id { get; set; }
public string EnvironmentName { get; set; }
public string EnvironmentNotes { get; set; }
public virtual ICollection<CounterDetail> CounterDetails { get; set; }
};
public class CounterData
{
[Key]
[Column(Order = 1)]
public DateTime counterTime { get; set; }
[Key]
[Column(Order = 2)]
public int counterName { get; set; }
[Key]
[Column(Order = 3)]
public Guid EnvId {get; set;}
public int count { get; set; }
[ForeignKey("EnvId")]
public virtual CockpitEnvironment Machine { get; set; }
}
App.config
:
<connectionStrings>
<add name="CounterDbString"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Counters_Test;Integrated Security=True;Connect Timeout=30"
providerName="System.Data.SqlClient"/>
</connectionStrings>
使用 VS2015,我在调试 (F5) 时收到此错误。 简单地停止调试器并重新启动后,问题就消失了。
如果在您的数据库尚未创建时出现这种情况,通常是连接字符串问题或数据库初始值设定项问题。 您的连接字符串看起来不错,因此它可能在实例构造函数中包含初始化程序。 尝试将初始化程序移动到静态构造函数:
public class CounterContext : DbContext
{
static CounterContext // runs once
{
Database.SetInitializer<CounterContext>(new CreateDatabaseIfNotExists<CounterContext>());
}
public CounterContext()
: base("name=CounterDbString") { }
public DbSet<CounterData> CounterDetails { get; set; }
public DbSet<Environment> Environments { get; set; }
}
这对我有用:创建上下文后初始化数据库
context.Database.Initialize(force: false);
对我来说,问题是它是静态的或切碎的功能......
将其更改为Public 。
线程安全:此类型的任何公共静态(在 Visual Basic 中共享)成员都是线程安全的。 不保证任何实例成员都是线程安全的。
在这里找到
我发现这个问题似乎是因为 Controller 不负责处理 DataContext 并且它保持打开状态。 您可以在 DataContext 端或控制器端或两者都处理此问题。
我在我的 DataContext 中这样做:
public partial class Model1 : DbContext
{
public Model1()
: this(true)
{ }
public Model1(bool enableLazyLoading = true)
: base("name=Model1")
{
// You can also do this instead of the other lines
//Database.SetInitializer<Model1>(new CreateDatabaseIfNotExists<Model1>());
//this.Configuration.LazyLoadingEnabled = false;
Database.SetInitializer<Model1>(null);
this.Configuration.ProxyCreationEnabled = false;
((IObjectContextAdapter)this).ObjectContext.ContextOptions.ProxyCreationEnabled = enableLazyLoading;
((IObjectContextAdapter)this).ObjectContext.ContextOptions.LazyLoadingEnabled = enableLazyLoading;
}
这在控制器中:
public class ReportController : Controller
{
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
然后你有你正常的东西之后......
public ActionResult Index()
{
//....
}
但是你为什么要这样抓取数据? 为什么要使用单独的类? 这应该都发生在控制器中。 并且您不想尝试使其在所有内容中都公开和静态 - 它是动态的,需要按控制器调用和处理,而不是保持打开状态。
我会这样做:
public class ReportController : Controller
{
CounterContext db = new CounterContext();
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
public void AddCockpitEnvironmentDetails(IList<Environment> environmentList)
{
// You could've gotten it like this instead of passing it in...
// IEnumerable<Environments> environmentList = db.Environments;
foreach (Environment entity in environmentList)
{
db.Environments.Add(entity);
}
db.SaveChanges();
}
....
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.