.net 如何防止DbContext更改数据库?

.net 如何防止DbContext更改数据库?,.net,database,entity-framework,orm,code-first,.net,Database,Entity Framework,Orm,Code First,我正在学习实体框架(目前使用的是EF6测试版),并在现有数据库上使用代码优先模式。实体和DbContext类是使用T4模板自动创建的 我想防止DbContext在运行时创建/更改数据库中的任何内容 我该怎么做?将上下文的初始化器设置为null 这样,当应用程序启动时,数据库将保持其现有状态 请注意,如果在更改dbContext类和/或数据库架构后尝试运行应用程序,将出现异常,因为您的数据库架构将不再符合上下文的要求。执行启用迁移命令时,您将看到文件夹/Migrations,在该文件夹下可以找到名

我正在学习实体框架(目前使用的是EF6测试版),并在现有数据库上使用代码优先模式。实体和
DbContext
类是使用T4模板自动创建的

我想防止
DbContext
在运行时创建/更改数据库中的任何内容


我该怎么做?

将上下文的初始化器设置为
null

这样,当应用程序启动时,数据库将保持其现有状态


请注意,如果在更改dbContext类和/或数据库架构后尝试运行应用程序,将出现异常,因为您的数据库架构将不再符合上下文的要求。

执行启用迁移命令时,您将看到文件夹/Migrations,在该文件夹下可以找到名为Configuration.cs的文件。默认情况下,在该文件的构造函数中,有一个属性设置为值:

 AutomaticMigrationsEnabled = false;
这将确保您的数据库不会自动迁移,而是通过手动调用每次迁移

但是,如果您的数据库大于您的域模型,即您只是在现有数据库的部分上操作,那么在应用程序启动中的某个位置(如果是ASP.NET应用程序,应用程序启动事件处理程序),您需要添加以下代码:

Database.SetInitializer<YourDbContext>(null);
再次编辑:

我想知道你想要实现什么样的场景。如果您有现有数据库,并且只想手动更新,则可以采用以下方法:

  • 使用DbContext生成器模板生成DbContext和实体 从现有数据库
  • 运行并启用迁移
  • 是否添加迁移初始值
  • 如果一切都完成了,步骤3应该生成空迁移 对。你可以删除它
  • 现在,无论何时进行更改,都需要进行添加迁移 改名。除非您这样做,否则这不会进入数据库 更新数据库

  • 我在DBFirst和EF 6.1中遇到了这个问题,它基于EntityName创建了一个新表。所以我修改了OnModelCreating虚拟方法来映射我的表

    因此,如果EntityName被命名为MyStuffs,因为默认情况下EntityNames是复数的,您可以选择在EF生成期间取消选择它。在我的例子中,向导正在生成表的复数版本

    public class MyContext: DbContext
    {
        public MyContext()
            : base("name=MyEntityConnectionName")
        {
        }
        public MyContext(string connectionString)
            : base(connectionString)
        {
        }
        #region methods
    
        public static MyContext Create()
        {
            return new MyContext();
        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            // Map Entities to their tables.
            modelBuilder.Entity<MyModel>().ToTable("MyStuff"); //prevent a new table from being added since we added a mapping
        }
    
        #endregion
        public virtual DbSet<MyModel> MyEntities{ get; set; }
    }
    
    公共类MyContext:DbContext
    {
    公共MyContext()
    :base(“name=MyEntityConnectionName”)
    {
    }
    公共MyContext(字符串连接字符串)
    :基本(连接字符串)
    {
    }
    #区域方法
    公共静态MyContext创建()
    {
    返回新的MyContext();
    }
    模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
    {
    基于模型创建(modelBuilder);
    //将实体映射到它们的表。
    modelBuilder.Entity().ToTable(“MyStuff”);//防止添加新表,因为我们添加了映射
    }
    #端区
    公共虚拟数据库集myenties{get;set;}
    }
    
    您是如何创建数据库的?默认情况下,EF Code First会向数据库中添加一个表,以便能够判断模型是否已更改。如果数据库未通过codefirst/migrations验证,则数据库中没有数据,EF将不会接触数据库的架构。如果您谈论的是数据-任何时候调用.SaveChanges()都可以添加/修改/删除数据库中的数据如果没有创建数据库,则定义不会更改数据库。它确实创建了新对象,因为我最初没有正确映射模式。我最终在默认dbo模式中重新创建了所有表。是的,它创建了新对象,因为它找不到任何对象,因为它们没有在默认模式中定义。请注意,由于它创建了表,它还添加了迁移历史记录表,其中保存了有关模型的信息。因此,它能够判断出模型已经改变了,但与它创建的表相比,并不是已经存在的表。它还将使用它创建的表,而不是原始表。禁用初始值设定项后,如果更改模型,则模型将不再与数据库匹配,并可能导致运行时问题或数据损坏。应使用
    .ToTable(tableName,schemaName)
    映射到非默认架构中的表。我不能阻止引用上下文程序集的任何其他程序集更改其初始值设定项,对吗?我真的不喜欢那样(我希望如果上下文设置为允许数据库更改的方式,我可以在SaveChanges上抛出一个异常。我想这不是用来这样使用的。如果您关心正在更改的数据库结构,您可以将上下文的连接字符串改为不给它create/alter table privi权限的字符串leges。如果您担心现有表的内容被更改,可以使用对要保护的表具有只读权限的连接字符串。编辑:要澄清,您需要设置新的(受限的),并更改连接字符串,以便使用这些帐户进行连接。要解决此问题,请执行以下操作:“如果上下文的设置方式允许数据库更改,我希望可以在SaveChanges上引发异常。”,我已修改了我的帖子。请检查编辑之间的解决方案,这可能会对您有所帮助。@ThinTim我没有为该dbcontext使用专用连接字符串,它可以用于任何DBConnection实例。如果由于某种原因,某个用户未被授予对某个表的权限,则我更希望应用程序抛出SecurityException rat无论如何,她不只是获取/写入数据。这是一件重要的事情,恐怕我不能置之不理。:我不确定我是否理解你的问题。如果你不想让你的应用程序更新
    public class MyContext: DbContext
    {
        public MyContext()
            : base("name=MyEntityConnectionName")
        {
        }
        public MyContext(string connectionString)
            : base(connectionString)
        {
        }
        #region methods
    
        public static MyContext Create()
        {
            return new MyContext();
        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            // Map Entities to their tables.
            modelBuilder.Entity<MyModel>().ToTable("MyStuff"); //prevent a new table from being added since we added a mapping
        }
    
        #endregion
        public virtual DbSet<MyModel> MyEntities{ get; set; }
    }