【问题标题】:How do you update an edmx file with database changes?如何使用数据库更改更新 edmx 文件?
【发布时间】:2012-03-31 06:42:52
【问题描述】:

我有一个 edmx 文件,我更改了数据库中的一个表。我知道有一个“从数据库更新模型”向导,但是在很多情况下这是没用的。

例如,如果我将字段从非 null 更改为可为 null,或者如果我删除字段,则更新模型不会反映更改。我必须删除实体并将其重新添加,以使更改出现在我的模型中。

根据以下问题: How do I propagate database changes to my .edmx file?

其中一个答案似乎说了同样的话,您需要删除实体并将其重新添加。

这是确定的答案还是有更好的方法来做到这一点?

【问题讨论】:

标签: entity-framework edmx edmx-designer


【解决方案1】:

安全方式更新 EDMX:

如您所见,来自数据库的更新并不总是正确地更改现有属性。

根据我们对 EDMX 更新的日常使用(24 个月内有 100 次更新),我建议按照以下顺序更新 EDMX。

删除现有模型然后更新:

  1. 打开 EDMX 设计器
  2. Ctrl-A 全选
  3. 删除键删除设计器中的所有模型
  4. 重要提示:如果您使用 TFS 进行源代码控制,此时不要保存 EDMX!*
  5. 现在右键单击并选择“从数据库更新模型”以重新创建整个模型。
  6. 重建项目以传播更改

这显然会丢失您对模型所做的任何手动调整,但应尽可能避免手动调整。这使得整个过程在任何时候都可以重现(这是一件好事)。

重要提示:

  • 如果您在 Visual Studio 中打开了自动保存,则需要快速选择更新(上面的第 5 步)以避免自动保存保存所有内容。
  • 如果您使用 TFS 进行源代码控制,并且在清空 EDMX 后碰巧保存了它,TFS 会将所有生成的文件标记为“已删除”,并且再次更新 EDMX 可能会导致断开的文件不在源代码管理!
  • 此过程不会更新任何存储过程。此外,我发现刷新 EDMX 也不会更新仅返回类型已更改的存储过程(在 EF 6.1.1 中仍然是最新的)。

其他建议:

将您的 EDMX 保存在单独的库中。这也成为添加额外 TT 文件和部分类的好地方(例如,扩展 EDMX 模型的功能)。我还在这个库中放置了数据库上下文的任何扩展方法。 migration 文件在库中生成,也很好地包含了所有内容。

2015 年 4 月更新

Visual Studio 2013 的最新版本 4 似乎已经解决了很多 TFS 问题。我们现在可以看到 Visual Studio 签出生成的文件,如果它们未更改,则将其还原。以上步骤似乎仍然是最安全的方法。

2015 年 9 月更新

使用最新的 VS2013 第 5 版,如果在 EDMX 更新期间发生保存,我们仍然会遇到问题。在更新过程中,您仍然可能处于挂起删除导致您的tt 文件从源代码管理中删除的状态。秘诀是在第 4 步和第 5 步之间快速更新! :)

【讨论】:

  • 在从数据库更新模型后,是否有一种好方法可以始终将我的主键上的 StoreGeneratedPattern 设置为 Identity,因为或者我们的 ID 在 sql server 上默认为 newid()。
  • @JerryLiang:如前所述,对 EDMX 的所有自定义调整都会丢失。您要么必须使用默认 SQL 设置,要么在每次 EDMX 更新后重复您的自定义更改。默认的newid() 应该只适用于新插入的记录,所以我不确定StoreGeneratedPattern = Identity 实际上有什么区别。或许你可以澄清一下?
  • 在更新 edmx 时,有没有办法将数据库结构导出到 sql 文件?
  • @Bakudan:它不是为来回设计的,但理论上你可以从 edmx 生成的类生成一个 code-first 数据库.您通常需要使用 SQL Server Management Studio 等工具创建数据库创建脚本。
  • @Gone Coding 感谢您逐步分享此详细信息。对于像我这样阅读 Gone Coding 的答案为时已晚并成功从源代码控制中删除/断开文件的人,我所做的是在 edmx 文件(最好是整个数据层)上执行 Undo Pending Changes。然后我做了一个Get Latest 版本。发生的事情是我的tt 文件现在又回到了 SC。然后执行上述步骤。 HTH。
【解决方案2】:

重要的第一步是准确了解使用更新模型向导时会发生什么。

来自MSDN Library

ADO.NET 实体数据模型设计器(实体设计器)使用更新模型向导根据对数据库所做的更改来更新 .edmx 文件。作为此过程的一部分,更新模型向导会覆盖存储模型。更新模型向导还对概念模型和映射进行了一些更改,但仅在将对象添加到数据库时才进行这些更改。例如,当向数据库中添加表时,会将新实体类型添加到概念模型中,当向表中添加列时,会将新属性添加到实体类型中。有关对 .edmx 文件进行哪些更改的详细信息,请参阅Changes Made to an .edmx File by the Update Model Wizard

当您使用更新模型向导更新数据库时,它更新了 .edmx 文件中的存储模型,而不是概念模型。当对现有对象的定义进行更改时,仅更新存储模型;概念模型未更新。有关更新模型向导所做更改的完整说明,请参阅上面的“更新模型向导对 .edmx 文件所做的更改”链接。

以下是有关如何更新未由更新模型向导更新的对象的一些选项(基于您更改列定义的场景):

  1. 使用更新模型向导(更新存储模型),使用设计器打开 .edmx 文件(默认),找到所需的标量属性并在“属性”窗口中编辑所需的属性。
  2. 使用更新模型向导(更新存储模型),使用 XML 编辑器打开 .edmx 文件,在 CSDL(概念模型)部分找到所需的属性并更改所需的属性。这与选项 1 基本相同,但您正在直接编辑 XML(查找和替换在这里可能很有用)。
  3. 在模型浏览器中,从概念模型的实体类型部分删除所需的实体,并从存​​储模型的表/视图部分删除所需的表。然后使用更新模型向导将其添加回来。

最佳选择取决于给定的场景。例如,如果您只是更改了一列的定义,那么选项 1 可能是您的最佳选择。如果您更改了单个表中多个列的定义,那么选项 3 可能是您的最佳选择。如果您更改了跨多个表使用的列(例如主键/外键),那么直接编辑 .edmx XML 可能是您的最佳选择。

【讨论】:

  • 太棒了!非常准确!
  • 这是金子!谢谢!
  • 谢谢...了解它的工作原理...大多数情况下,从 EDMX 中删除表,然后从数据库中更新对我有用。现在我知道为什么了
  • 什么“概念模型”?那是什么?除了模型的概念?
【解决方案3】:

如果我理解您的问题和您的示例,一旦您从数据库步骤执行更新模型并且您坐在 Model.edmx 图上,您可以突出显示您想要更改的类中的属性并显示属性,并将其 Nullable 属性更改为 Nullable: True。这至少是一种方法。

我相信这里的想法是概念模型(不会从非空更改为可空)实际上可能与基础数据库表不同,因此它不会改变那部分,而这种差异可能正是你打算。我处理此问题的两种方法是按照您提到的那样进行删除和添加,或者更常见的是我按照我提到的那样手动设置属性。

【讨论】:

  • 是的,我想我按照你说的做了。就我而言,我有一个不可为空的字段,制作了我的 edmx 文件。然后我将我的实体更改为可为空的。然后它抱怨实体是时数据库不可为空。所以我将数据库更新为可以为空,并使用“从数据库更新模型”。但是,正如您所指出的,它不会更改 null/not null 属性。在这种情况下,我不能只更改实体而不产生错误。所以我删除并添加了实体,没关系。没什么大不了的,但我想知道是否有更好的方法。
【解决方案4】:

考虑一下我在现有表中添加了一个新列 (c1)。然后要在我现有的实体模型中更新相同的内容,我会执行以下操作。

我将在记事本 ++ 中打开 .edmx 文件。

我会在必要时将属性 c1 添加到 .edmx 文件中。例如,我会在每个 c0 节点下方添加 c1 节点。

    <EntityType Name="table">
      <Key>
        <PropertyRef Name="Id" />
      </Key>
      <Property Name="Id" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
      <Property Name="c0" Type="nvarchar(max)" />
      <Property Name="c1" Type="nvarchar(max)" />
    </EntityType> 

在 Visual Studio 中重新加载项目。

最后将属性 c1 添加到模型中。

【讨论】:

    【解决方案5】:
    1. 首先,双击.edmx文件
    2. 其次,在空白处右击,选择“Update Model From Database”
    3. 第三,选择菜单栏上的刷新标签。
    4. 最后,选择要刷新的表,然后选择Finish..

    【讨论】:

    • 不正确。无法选择要刷新哪些表 - 所有表始终使用已接受答案中描述的流程进行刷新。
    【解决方案6】:

    第 1 步: 双击 .edmx 文件。 (图表窗口将打开)

    第 2 步: 在图表窗口中,右键单击并选择Update model from database...(现在它只会在更新存储中更新,而不会在模型中更新)

    第 3 步: 右键单击 Model.tt 文件,然后单击 Run Custom Tool(现在它也会在模型中更新)

    就是这样!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-22
      • 1970-01-01
      • 1970-01-01
      • 2018-02-17
      • 2012-02-28
      • 2016-01-08
      相关资源
      最近更新 更多