如何使用数据库更改更新edmx文件?

时间:2012-03-14 18:45:26

标签: entity-framework edmx edmx-designer

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

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

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

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

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

6 个答案:

答案 0 :(得分:56)

安全方式更新EDMX:

如您所见,数据库更新并不总能正确更改现有属性。

从我们日常使用EDMX更新(超过24个月的100次更新),我建议使用以下顺序更新EDMX。

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

  1. 打开EDMX设计师
  2. Ctrl-A选择所有
  3. 删除键以删除设计器中的所有模型
  4. 重要提示:如果您使用TFS进行源代码管理,请不要在此时保存EDMX!*
  5. 现在右键单击并选择"从数据库更新模型"再次重建整个模型。
  6. 重建项目以传播更改
  7. 这显然会丢失您对模型所做的任何手动调整,但如果可能,应避免手动调整。这使得整个过程可以随时重现(这是一件好事)。

    重要说明:

    • 如果在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第5版,如果在EDMX更新期间进行保存,我们仍然会遇到问题。在更新期间,您仍然可以处于暂挂删除状态导致tt文件从源代码管理中删除的状态。秘诀是在第4步和第5步之间快速更新! :)

答案 1 :(得分:36)

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

来自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. 从模型浏览器中,从概念模型的“实体类型”部分中删除所需的实体,并从存​​储模型的“表/视图”部分中删除所需的表。然后使用更新模型向导将其添加回来。
  4. 最佳选择取决于给定的方案。例如,如果您只是更改了一列的定义,那么选项1可能是您的最佳选择。如果您更改了单个表中多个列的定义,则选项3可能是您的最佳选择。如果您更改了在多个表(例如主键/外键)中使用的列,则直接编辑.edmx XML可能是您的最佳选择。

答案 2 :(得分:1)

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

我认为这里的想法是概念模型(没有从非null变为可空)实际上可能与底层数据库表不同,因此它不会改变那部分,这种差异可能正是你打算。我处理这个的两种方法是做删除&如上所述添加,或者更常见的是我手动设置我提到的属性。

答案 3 :(得分:1)

考虑我已将新列(c1)添加到现有表中。然后在我现有的实体模型中更新它,我会做以下几点。

我将在notepad ++中打开.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添加到模型中。

答案 4 :(得分:0)

  1. 首先,双击.edmx文件
  2. 其次,右键单击空白区域并选择“从数据库更新模型”
  3. 第三步,在菜单栏上选择“刷新”选项卡。
  4. 最后,选择要刷新的表,然后选择完成..

答案 5 :(得分:0)

步骤1: 双击 .edmx 文件。 (将打开“图”窗口)

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

步骤3: 右键点击 Model.tt 文件,然后点击 运行自定义工具 l (现在它也会在模型中更新)

就是这样!