【问题标题】:Stop Entity Framework from modifying database阻止实体框架修改数据库
【发布时间】:2020-10-31 04:20:00
【问题描述】:

我开始使用实体框架的代码优先方法,主要是为了我可以用注释装饰我的属性,以便在我的视图中显示(否则,现在我必须创建一个几乎与实体框架为我生成的相同,因此我可以添加注释,然后将数据从一个对象复制到下一个对象)。

现在看起来当我启动我的应用程序时它正在尝试创建一个数据库。

我不希望实体框架永远修改我的数据库。不,从来没有。甚至不要尝试。修改数据库真的没那么难;如果我自己这样做,我会感觉更舒服。设计数据库时,我不需要框架来牵手。

我可以告诉框架停止尝试修改我的数据库吗?我现在非常犹豫是否使用代码优先,因为它试图修改我的数据库这一事实相当可怕。即使在开发中,我也不想看到它发生。

我运气不好?

【问题讨论】:

  • 听起来您的模型与您的数据库不完全匹配。您可以尝试使用数据库的副本并指向 EF。让它创建修改数据库并比较差异,然后相应地修改您的模型。您还应该看看 EntityTypeConfiguration 泛型类。
  • 修改架构或修改数据?
  • 我们中的一些人只是不相信这些自动迁移,并且认为设计和设置数据库非常重要,因此手动完成是完全合理的。但是让 EDMX 远离我……这样做的另一个原因:一个团队可以在数据库上工作,而另一个团队可以设置类/模型以匹配 - 大致平行。如果有任何变化,您不必重新搜索迁移。只需更新您的注释等。
  • 在 Entity Framework 核心中放弃此行为可能很有用。

标签: c# .net entity-framework entity-framework-4


【解决方案1】:

如果您不希望 EF 创建数据库,可以禁用数据库初始化程序:

public class SchoolDBContext: DbContext 
{
    public SchoolDBContext() : base("SchoolDBConnectionString")
    {            
        //Disable initializer
        Database.SetInitializer<SchoolDBContext>(null);
    }
    public DbSet<Student> Students { get; set; }
    public DbSet<Standard> Standards { get; set; }
}

http://www.entityframeworktutorial.net/code-first/turn-off-database-initialization-in-code-first.aspx

【讨论】:

  • 你可以把它放在上下文类的静态构造函数中,如这个示例视频:msdn.microsoft.com/en-us/data/jj572367
  • 视频中没有显示。请看这里:entityframeworktutorial.net/code-first/… 重要的是不要在数据库前面使用它
  • 可以通过添加此代码的位置来改进此答案。
  • 仍然无法相信它会默认使用您的数据库。我不知道他们为什么不抛出异常来解释你必须做出的明确选择
  • @Simon_Weaver 这就是代码的重点。您编写模型来定义/创建数据库。
【解决方案2】:

如果您想使用 EF 但从不修改数据库,那么您可能不想先编写代码。您可能首先想要更像数据库的东西。

http://blogs.msdn.com/b/adonet/archive/2011/03/15/ef-4-1-model-amp-database-first-walkthrough.aspx

来自答案 cmets 的链接:
http://automapper.codeplex.com/
Getting Started with AutoMapper

编辑:我误解了目标,you should reference this answer where the following correct code was given:

If you don't want EF to create your database, you can disable the database initializer

Database.SetInitializer<MyContext>(null);

【讨论】:

  • 我同意数据库首先 听起来 像我想要的那样,但我试图解决必须创建一个与模型几乎相同的类的问题为我生成。我必须创建一个几乎相同的类,以便我可以用注释装饰属性以在我的视图中显示(例如强制验证)。这导致我不得不遍历所有“EF”对象并将它们复制/映射到带有注释的新对象。
  • 我会说你永远不应该将你的数据库模型对象传递给你的视图。通常,您创建另一个类,然后将其传递给您的视图,该视图仅包含该视图可用的属性。然后,您将使用您的验证属性装饰该类
  • @AnthonyShaw - 我还没有看到很多人这样做的例子,但这正是我现在正在做的事情。我想我对此感到担心,因为它看起来像是很多平凡的复制/映射工作。是否有一种模式可用于将数据库模型对象转换为在视图中显示的对象?你平时是怎么做的?
  • @Ek0nomik 那么automapper 可能是一个解决方案。考虑到一些限制(大约相同的字段名称等),它可以自动将属性从一个类复制到另一个类。但是,您仍然必须定义类(您自己的模型)。
  • @Ek0nomik,就像 CodeCaster 建议的那样,我创建 ViewModel,如果你愿意的话,使用特定视图所需的属性,并使用 AutoMapper(automapper.codeplex.com 或通过 NuGet 获得)它使用映射属性的反射(只要它们的名称匹配)。我最初认为它是为了进行平凡的重复,但随着我继续这样做,我发现很多情况下将我的实际对象传递给视图会导致问题。
【解决方案3】:

当你声明你是初始化器时,使用基类:

public class DatabaseInitialiser : CreateDatabaseIfNotExists<MyContext>

而不是:

public class DatabaseInitialiser : RecreateDatabaseIfModelChanges<MyContext>

或者如果你使用:

Database.SetInitializer<MyContext>(new RecreateDatabaseIfModelChanges<MyContext>);

将其替换为:

Database.SetInitializer<MyContext>(new CreateDatabaseIfNotExists<MyContext>);

【讨论】:

    【解决方案4】:

    由于code first 几乎完全符合您的描述,我不明白您的问题。

    如果您不希望 EF 摆弄您的数据库,请从您现有的数据库中generate a model

    【讨论】:

    • 对,但是如果我从我的数据库生成模型,那么我会丢失在视图中显示数据所需的数据注释。这会导致大量重复工作;本质上是创建一个与生成的模型相同的类,然后用注释装饰这些属性。我试图避免与此相关的所有复制工作。
    • 您可以通过创建部分类或伙伴类(MetadataAttribute)来装饰生成的类。
    • 有一些例子,你想做 Code Second,数据库存在但关系不存在,或者你处理 View,需要 Code Second 方法。
    • 您可能想要关闭此功能的一个原因是,您刚刚收到一个异常,告诉您 EF 试图在您的应用程序启动时删除您的整个数据库!
    • 完全有效的代码首先用于生成数据库更新,但在用户/dbadmin的控制下,而不是“智能地”自行擦除所有数据。
    【解决方案5】:

    我意识到这个线程很旧,但希望 OP 找到了答案。如果没有……

    让 Visual Studio 从现有数据库生成 EF6 实体类:

    https://www.entityframeworktutorial.net/code-first/code-first-from-existing-database.aspx

    然后添加(如前所述):

    Database.SetInitializer<SchoolDBContext>(null);
    

    阻止 EF6 干扰数据库。

    请注意,自动生成的类的一个潜在问题是生成的代码使用 fluent。

    【讨论】:

    • 我再说一遍以确保添加了那行代码。有人可能会使用 VS 生成实体类,然后不添加 SetInitializer 部分。需要这行代码来防止 EF 创建数据库。
    • 那么,当有 三个 答案说明这一点时,为什么会更确定呢?重复的答案在 Stack Overflow 是一个相当大的问题。它们不会增加任何价值,只会增加噪音。
    • 我的答案不是重复的。 OP 提出了两个问题:阻止 EF 修改数据库;后来说他不想创建课程。前者得到了回答,但没有人回答后者。我发布的链接回答了后者,但是仍然需要 SetInitailizer 代码。
    • 不,他们想使用自己的类(“以便我可以用注释装饰我的属性”),而不是 EF 生成的类。此外,链接不是答案。
    猜你喜欢
    • 1970-01-01
    • 2011-03-10
    • 2012-08-18
    • 2014-09-09
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多