控制台/库应用程序中的实体框架初始化程序

时间:2014-05-07 09:53:57

标签: c# entity-framework

我目前正在开发一个拥有控制台应用程序和少量库项目的项目。一个库项目是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和相关类不保证是线程安全的。

如何在创建模型之前延迟使用上下文? 我目前对此有点困惑,任何关于如何解决这个问题的想法都将受到赞赏。

谢谢!

3 个答案:

答案 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()