51

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

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

根据以下问题: 如何将数据库更改传播到我的 .edmx 文件?

其中一个答案似乎说的是同一件事,即您需要删除实体并将其重新添加。

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

4

6 回答 6

62

以安全的方式更新 EDMX :

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

从我们日常使用 EDMX 更新(24 个月内更新 100 次)来看,我建议按照以下顺序更新 EDMX。

删除现有模型,然后更新:

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

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

重要笔记:

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

附加建议:

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

2015 年 4 月更新

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

2015 年 9 月更新

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

于 2014-05-27T09:39:37.733 回答
45

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

MSDN 库

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

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

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

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

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

于 2012-03-14T20:39:06.897 回答
1

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

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

于 2012-03-14T19:02:00.270 回答
1

考虑我在现有表中添加了一个新列(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 添加到模型中。

于 2016-11-23T15:37:13.010 回答
0

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

步骤 2:在图表窗口中,右键单击并选择从数据库中更新模型...(现在它只会在更新存储中更新,而不会在模型中更新)

步骤 3:右键单击Model.tt文件并单击Run Custom Tool l(现在它也会在模型中更新)

而已!

于 2019-02-16T08:08:12.833 回答
0
  1. 首先,双击 .edmx 文件
  2. 其次,右键单击空白区域并选择“从数据库更新模型”
  3. 第三,选择菜单栏上的刷新选项卡。
  4. 最后,选择要刷新的表,然后选择 Finish..
于 2018-03-29T13:33:55.577 回答