复杂类型-EF 设计器Complex Types - EF Designer

本主题演示如何将复杂类型映射到 Entity Framework Designer (EF 设计器)以及如何查询包含复杂类型属性的实体。

下图显示了在使用 EF 设计器时使用的主窗口。

EF 设计器

备注

在生成概念模型时,有关未映射的实体和关联的警告可能会显示在“错误列表”中。 您可以忽略这些警告,因为在您选择从模型生成数据库后,错误将消失。

什么是复杂类型What is a Complex Type

复杂类型是实体类型的非标量属性,实体类型允许在实体内组织标量属性。 与实体相似,复杂类型由标量属性或者其他复杂类型属性组成。

使用表示复杂类型的对象时,请注意以下事项:

  • 复杂类型没有键,因此不能独立存在。 复杂类型只能作为实体类型或其他复杂类型的属性而存在。
  • 复杂类型不能参与关联且不能包含导航属性。
  • 复杂类型属性不能为 null。 当调用DbContext 并且遇到 null 复杂对象时,会发生**InvalidOperationException **。 复杂对象的标量属性可以为 null
  • 复杂类型不能从其他复杂类型继承。
  • 必须将复杂类型定义为
  • 调用DetectChanges时,EF 检测对复杂类型对象上的成员所做的更改。 调用以下成员时,实体框架自动调用DetectChangesDbSetDbSet DbSet 、DbSetDbSet、DbContext 、DbContext 、GetValidationErrors、DbContext、DbChangeTracker、、。

将实体的属性重构为新的复杂类型Refactor an Entity’s Properties into New Complex Type

如果概念模型中已经有一个实体,可能想要将某些属性重构为复杂类型属性。

在设计器图面上,选择一个或多个实体属性(不包括导航属性),然后右键单击并选择 “ 重构-> 移动到新的复杂类型“。

重构

具有选定属性的新复杂类型将添加到模型浏览器。 此复杂类型会被赋予一个默认名称。

新创建类型的复杂属性将替换选定属性。 所有属性映射都将保留。

重构2

创建新的复杂类型Create a New Complex Type

你还可以创建不包含现有实体的属性的新复杂类型。

右键单击 “模型浏览器” 中的 “复杂类型“ 文件夹,指向 “ AddNew 复杂类型 … “。 或者,你可以选择 “复杂类型“ 文件夹,并按键盘上的 “ 插入 键。

添加新的复杂类型

新复杂类型将添加到具有默认名称的文件夹。 你现在可以将属性添加到该类型。

向复杂类型添加属性Add Properties to a Complex Type

复杂类型的属性可以是标量类型或现有的复杂类型。 但是,复杂类型属性无法具有循环引用。 例如,复杂类型 OnsiteCourseDetails 不能具有复杂类型 OnsiteCourseDetails的属性。

可以通过下面列出的任何方式向复杂类型添加属性。

  • 在模型浏览器中右键单击复杂类型,指向 “ 添加“,再指向 “ 标量属性“ 或 “ 复杂属性“,然后选择所需的属性类型。 或者,您可以选择一种复杂类型,然后按下键盘上的 Insert 键。

    向复杂类型添加属性

    新属性将添加到具有默认名称的复杂类型。

  • 或 -

  • 右键单击EF 设计器图面上的实体属性,选择 “ 复制“,然后在 “模型浏览器“ 中右键单击复杂类型,然后选择 “ 粘贴“。

重命名复杂类型Rename a Complex Type

重命名复杂类型时,将通过项目更新对类型的所有引用。

  • 模型浏览器中,慢慢地双击复杂类型。 名称将选定并处于编辑模式。

  • 或 -

  • 模型浏览器中右键单击复杂类型,然后选择 “ 重命名“。

  • 或 -

  • 在模型浏览器中选择复杂类型,按 F2 键。

  • 或 -

  • 模型浏览器中右键单击复杂类型,然后选择 “ 属性“。 在 “ 属性“ 窗口中编辑该名称。

将现有复杂类型添加到实体,并将其属性映射到表列Add an Existing Complex Type to an Entity and Map its Properties to Table Columns

  1. 右键单击某个实体,指向 “ 添加新项”,然后选择 “ 复杂属性“。 具有默认名称的复杂类型属性将添加到该实体。 默认类型(从现有复杂类型中选择)将指派给该属性。

  2. 将所需的类型分配给 “ 属性“ 窗口中的属性。 在将复杂类型属性添加到实体后,必须将其属性映射到表列。

  3. 右键单击设计图面或 模型浏览器中的某个实体类型 然后选择 “ 表映射“。 表映射显示在 “窗口中的” 映射详细信息“窗口中。

  4. 展开 “ 映射”,以 <表名称> “节点。 此时将显示 节点的 列映射

  5. 展开 “ 列映射 “ 节点。 出现一个包含表中所有列的列表。 列映射的默认属性(如果有)将在 “ 值/属性“ 标题下列出。

  6. 选择要映射的列,然后右键单击相应的 值/属性 “字段。 出现一个包含所有标量属性的下拉列表。

  7. 选择适当的属性。

    映射复杂类型

  8. 对每一个表列重复步骤 6 和 7。

备注

若要删除列映射,请选择要映射的列,然后单击 “ 值/属性“ 字段。 然后,从下拉列表中选择 “删除“。

将函数导入映射到复杂类型Map a Function Import to a Complex Type

函数导入基于存储过程。 若要将函数导入映射到复杂类型,相应存储过程返回的列必须在数量上与复杂类型的属性匹配并且必须具有与属性类型兼容的存储类型。

  • 双击要映射到复杂类型的已导入函数。

    函数导入

  • 填入新函数导入的设置,如下所示:

    • 在 “ 存储过程名称“ 字段中指定要为其创建函数导入的存储过程 字段。 此字段是一个下拉列表,其中显示存储模型中的所有存储过程。

    • 在 “ 函数导入名称 “ 字段中指定函数导入的名称。

    • 选择 “ 复杂 “ 作为返回类型,然后通过从下拉列表中选择适当的类型来指定特定的复杂返回类型。

      编辑函数导入

  • 单击 “确定” 。 此时将在概念模型中创建函数导入项。

自定义函数导入的列映射Customize Column Mapping for Function Import

  • 右键单击模型浏览器中的函数导入,然后选择 “ 函数导入映射“。 此时将显示 “ 映射详细信息“ 窗口,其中显示函数导入的默认映射。 箭头指示列值和属性值之间的映射。 默认情况,假设列名称与复杂类型的属性名称相同。 默认的列名称以灰色文本显示。
  • 如有必要,请更改列名称以匹配由对应于函数导入的存储过程返回的列名称。

删除复杂类型Delete a Complex Type

删除复杂类型时,从概念模型删除类型,并且将删除该类型所有实例的映射。 但是,不更新对类型的引用。 例如,如果实体具有类型为 ComplexType1 的复杂类型属性,并且在模型浏览器中删除了 ComplexType1,则不会更新相应的实体属性。 模型将不会验证,因为它包含引用已删除复杂类型的实体。 可以使用实体设计器更新或删除对已删除复杂类型的引用。

  • 在模型浏览器中右键单击复杂类型,然后选择 “ 删除“。

  • 或 -

  • 在模型浏览器中选择复杂类型,然后按键盘上的“Delete”键。

查询包含复杂类型属性的实体Query for Entities Containing Properties of Complex Type

下面的代码演示如何执行一个查询,该查询返回包含复杂类型属性的实体类型对象的集合。

  1. using (SchoolEntities context = new SchoolEntities())
  2. {
  3. var courses =
  4. from c in context.OnsiteCourses
  5. order by c.Details.Time
  6. select c;
  7. foreach (var c in courses)
  8. {
  9. Console.WriteLine("Time: " + c.Details.Time);
  10. Console.WriteLine("Days: " + c.Details.Days);
  11. Console.WriteLine("Location: " + c.Details.Location);
  12. }
  13. }