我目前正在开发一个拥有控制台应用程序和少量库项目的项目。一个库项目是EF代码第一个项目,它包含我的模型和上下文:
public class MyDbContext: DbContext
{
public MyDbContext() : base("MyConnectionString")
{
}
public DbSet<File> Files { get; set; }
}
我还有一个单例类,我想通过它来访问数据库。单身人士看起来像这样:
public sealed class DbLogger : IDbLogger
{
private static readonly DbLogger instance = new DbLogger();
private static MyDbContext ctx = new MyDbContext();
static DbLogger() {
Database.SetInitializer<MyDbContext>(new DbInitializer());
}
private DbLogger() { }
public static DbLogger Instance
{
get {
return instance;
}
}
public void AddFile(string fileName)
{
ctx.Files.Add(new File() { FullPath = fileName });
}
}
db初始化程序非常简单,只是实现了CreateDatabaseIfNotExists。种子还没有做什么。
在所有引用库项目的控制台中,我只想将其用作:
private DbLogger logger = DbLogger.Instance;
并使用以下命令从任务中调用记录器:
logger.AddFile("myFileName");
当应用程序进入logger.AddFile调用时,我得到以下异常:
类型&#39; System.InvalidOperationException&#39;的例外情况发生在 EntityFramework.dll但未在用户代码中处理
附加信息:模型时不能使用上下文 被创造。如果使用上下文,则可能抛出此异常 在OnModelCreating方法内部或者相同的上下文实例 由多个线程同时访问。请注意实例成员 DbContext和相关类不保证是线程安全的。
如何在创建模型之前延迟使用上下文? 我目前对此有点困惑,任何关于如何解决这个问题的想法都将受到赞赏。
谢谢!
答案 0 :(得分:2)
我推荐这种方法
public void AddFile(string fileName){
using(var ctx = new MyDbContext() ){
ctx.Files.Add(new File() { FullPath = fileName });
ctx.SaveChanges();
}
}
您应该只在需要时使用DbContext。打开数据库连接,与数据库交互并关闭连接。 using语句负责打开和关闭数据库连接。
编辑 - 使用SaveChanges()
进行更新答案 1 :(得分:0)
ad to @Kunukn回答:
我认为你应该责怪
private static MyDbContext ctx = new MyDbContext();
它试图在数据库初始化程序运行之前访问上下文。
如果您不想在每次AddFile()调用上创建新的上下文,请尝试在静态构造函数中创建上下文。
答案 2 :(得分:0)
我看到了行
的问题Database.SetInitializer(new DbInitializer());
如果您使用
public void AddFile(string fileName){
using(var ctx = new MyDbContext() ){
ctx.Files.Add(new File() { FullPath = fileName });
ctx.SaveChanges();
}
}
然后你的单身人士的目的没有得到解决,因为每次调用AddFile时它都会创建一个新的MyDbContext(这是推荐的)
但即使您坚持使用单个dbcontext对象,也应该创建一些 初始化fucntion,可能在创建对象后调用它。
可能类似于
private DbLogger logger = DbLogger.Instance;
logger.Initialize()