In the Entity Data Model, entities that are derived types can have associations with other derived types or with base types. The data model that is implemented in this topic uses the inheritance hierarchies shown in the topics How to: Define a Model with Table-per-Type Inheritance and How to: Define a Model with Table-per-Hierarchy Inheritance. The example in this topic modifies the association in the earlier table-per-hierarchy model by associating the derived Administrator type directly to the Department type instead of to the base type Person from which Administrator is derived. The second modification in this topic is a new association between DeptEngineering and DeptBusines, which are two entity types derived from the Department type.
You can implement this example by using the Entity Data Model Designer or by manually implementing the schemas. The basic model is most easily generated from the database by using the Entity Data Model Wizard. All but one of the required modifications can be made either in the designer or by editing the schemas in an XML editor.
Create the Database Used by the Storage Model
Use the following script with SQL Server Management Studio to generate the database that is used in this example. This is the same script that is used in the example How to: Define a Model with Table-per-Type Inheritance (Entity Framework). If you created the database for that example, go to Modify Database to Support Associations with Table-per-Type Derived Types.
To generate the database by using SQL Server Management Studio
In SQL Server Management Studio, on the File menu, point to New, and then select Database Engine Query.
Type either localhost or the name of another instance of SQL Server in the Connect to Database Engine dialog box, and then click Connect.
Paste the following Transact-SQL script in the query window, and then click Execute.
USE [master] GO CREATE DATABASE [SchoolData] GO USE [SchoolData] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DeptBusiness]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[DeptBusiness]( [BusinessDeptID] [int] NOT NULL, [LegalBudget] [money] NOT NULL, [AccountingBudget] [money] NOT NULL, CONSTRAINT [PK_DeptBusiness] PRIMARY KEY CLUSTERED ( [BusinessDeptID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DeptEngineering]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[DeptEngineering]( [EngineeringDeptID] [int] NOT NULL, [FiberOpticsBudget] [money] NOT NULL, [LabBudget] [money] NOT NULL, CONSTRAINT [PK_DeptEngineering] PRIMARY KEY CLUSTERED ( [EngineeringDeptID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DeptMusic]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[DeptMusic]( [DeptMusicID] [int] NOT NULL, [TheaterBudget] [money] NOT NULL, [InstrumentBudget] [money] NOT NULL, CONSTRAINT [PK_DeptMusic] PRIMARY KEY CLUSTERED ( [DeptMusicID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Course]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[Course]( [CourseID] [int] NOT NULL, [Title] [nvarchar](100) NOT NULL, [StartDate] [datetime] NOT NULL, [EndDate] [datetime] NOT NULL, [Credits] [int] NULL, CONSTRAINT [PK_Course] PRIMARY KEY CLUSTERED ( [CourseID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Person]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[Person]( [PersonID] [int] NOT NULL, [FirstName] [nvarchar](50) NOT NULL, [LastName] [nvarchar](50) NOT NULL, [HireDate] [datetime] NULL, [EnrollmentDate] [datetime] NULL, [PersonCategory] [smallint] NOT NULL, [AdminDate] [datetime] NULL, CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ( [PersonID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Enrollment]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[Enrollment]( [EnrollmentID] [int] NOT NULL, [CourseID] [int] NOT NULL, [StudentID] [int] NOT NULL, CONSTRAINT [PK_Enrollment] PRIMARY KEY CLUSTERED ( [EnrollmentID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[CourseInstructor]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[CourseInstructor]( [CourseInstructorID] [int] NOT NULL, [CourseID] [int] NOT NULL, [InstructorID] [int] NOT NULL, CONSTRAINT [PK_CourseInstructor] PRIMARY KEY CLUSTERED ( [CourseInstructorID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Department]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[Department]( [DepartmentID] [int] NOT NULL, [Name] [nvarchar](50) NOT NULL, [Budget] [money] NOT NULL, [StartDate] [datetime] NOT NULL, [Administrator] [int] NULL, CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED ( [DepartmentID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Enrollment_Course]') AND parent_object_id = OBJECT_ID(N'[dbo].[Enrollment]')) ALTER TABLE [dbo].[Enrollment] WITH CHECK ADD CONSTRAINT [FK_Enrollment_Course] FOREIGN KEY([CourseID]) REFERENCES [dbo].[Course] ([CourseID]) GO ALTER TABLE [dbo].[Enrollment] CHECK CONSTRAINT [FK_Enrollment_Course] GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Enrollment_Student]') AND parent_object_id = OBJECT_ID(N'[dbo].[Enrollment]')) ALTER TABLE [dbo].[Enrollment] WITH CHECK ADD CONSTRAINT [FK_Enrollment_Student] FOREIGN KEY([StudentID]) REFERENCES [dbo].[Person] ([PersonID]) GO ALTER TABLE [dbo].[Enrollment] CHECK CONSTRAINT [FK_Enrollment_Student] GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_CourseInstructor_Course]') AND parent_object_id = OBJECT_ID(N'[dbo].[CourseInstructor]')) ALTER TABLE [dbo].[CourseInstructor] WITH CHECK ADD CONSTRAINT [FK_CourseInstructor_Course] FOREIGN KEY([CourseID]) REFERENCES [dbo].[Course] ([CourseID]) GO ALTER TABLE [dbo].[CourseInstructor] CHECK CONSTRAINT [FK_CourseInstructor_Course] GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_CourseInstructor_Instructor]') AND parent_object_id = OBJECT_ID(N'[dbo].[CourseInstructor]')) ALTER TABLE [dbo].[CourseInstructor] WITH CHECK ADD CONSTRAINT [FK_CourseInstructor_Instructor] FOREIGN KEY([InstructorID]) REFERENCES [dbo].[Person] ([PersonID]) GO ALTER TABLE [dbo].[CourseInstructor] CHECK CONSTRAINT [FK_CourseInstructor_Instructor] GO IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Department_Administrator]') AND parent_object_id = OBJECT_ID(N'[dbo].[Department]')) ALTER TABLE [dbo].[Department] WITH CHECK ADD CONSTRAINT [FK_Department_Administrator] FOREIGN KEY([Administrator]) REFERENCES [dbo].[Person] ([PersonID]) GO ALTER TABLE [dbo].[Department] CHECK CONSTRAINT [FK_Department_Administrator]
Modify Database to Support Associations with Table-per-Type Derived Types
Use the following script in SQL Server Management Studio to modify the database that you created in the previous procedure. This script adds a foreign key to the table DeptEngineering to support associations with derived types.
To add foreign keys to support Table-per-Type derived types
In SQL Server Management Studio, on the File menu, point to New, and then select Database Engine Query.
Type either localhost or the name of another instance of SQL Server in the Connect to Database Engine dialog box, and then click Connect.
Paste the following Transact-SQL script in the query window, and then click Execute.
USE [SchoolData] GO ALTER TABLE [dbo].[DeptEngineering] ADD [RelatedBusinessDept] int GO ALTER TABLE [dbo].[DeptEngineering] WITH CHECK ADD CONSTRAINT [FK_DeptEngineering_DeptBusiness] FOREIGN KEY([RelatedBusinessDept]) REFERENCES [dbo].[DeptBusiness] ([BusinessDeptID]) GO ALTER TABLE [dbo].[DeptEngineering] CHECK CONSTRAINT [FK_DeptEngineering_DeptBusiness] GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Supports derived type mapping.' , @level0type=N'SCHEMA', @level0name=N'dbo', @level1type=N'TABLE', @level1name=N'DeptEngineering', @level2type=N'CONSTRAINT', @level2name=N'FK_DeptEngineering_DeptBusiness'
Implement Project and Data Model
To implement the project and data model before modifications
Create a new console application project in Visual Studio named
DerivedTypesAssociations.On the Project menu, select Add New Item, and add an ADO.NET Entity Data Model.
Name the new data model
SchoolData, and then click Add.In the Entity Data Model Wizard, select Generate from database and then click Next.
In the Choose Your Data Connection dialog box, select or create a connection to the
SchoolDatadatabase.Accept the default name for the object context,
SchoolDataEntities, and then click Next.In the Choose Your Data Objects dialog box, select the tables named
Person,Department,DeptBusiness, andDeptEngineering.Accept the default name,
SchoolDataModel, for the data model, and then click Finish.
Create Derived Types and Associations
After you complete the previous procedures, you can make modification to the data model that will be required to implement derived types and associations between derived types. The following steps modify the two entities, DeptEngineering and DeptBusiness, to make them table-per-type entities that are derived from the Department base class. In the following procedure, an Administrator type is derived from the Person type and an association is created between the derived Administrator type and the base type Department. The results of all these changes in the schemas can be seen in the complete edmx file at the end of the topic.
To create Person derived types and associations
Rename the entity set
PersontoPeople.Create a new entity derived from
PersonnamedAdministrator.Set the
BaseTypeattribute of theAdministratorentity toPerson.Delete the
AdminDateproperty of thePersonentity.Add a property
AdminDateof typeDateTimeto the newAdministratorentity.Set the
Nullableattribute of theAdminDateproperty to false.Map the
AdminDatecolumn of thePersontable to theAdminDateproperty of theAdministratorentity.Add a condition to the mapping:
<Condition ColumnName="AdminDate" IsNull="false">. You can do this in the designer by opening the Mapping Details window and adding the condition or by adding the condition to the edmx file in an XML editor.Delete the association created by the wizard between
DepartmentandPerson.Create a new association between
DepartmentandAdministrator.Set both
Endattributes of theDepartmentAdministratorassociation to1.Map the association between
DepartmentandAdministratorby mapping theAdministratorproperty of theDepartmenttable to theAdministratorcolumn and theDepartmentIDproperty to theDepartmentIDcolumn.Add a condition to the
DepartmentAdministratorassociation:<Condition ColumnName="Administrator" IsNull="False" />. This is the only step that you will have to do by manually editing the mapping schema in an XML editor.
To create Department derived types and associations
Rename the entity set
DepartmenttoDepartments.Delete the key properties of
DeptEngineeringandDeptBusiness.Set the
BaseTypeattribute ofDeptEngineeringtoDepartment.Set the
BaseTypeattribute ofDeptBusinesstoDepartment.Map the
EngineeringDeptIDcolumn of theDeptEngineeringtable to theDepartmentIDproperty of theDepartmententity.Map the
BusinessDeptIDcolumn of theDeptBusinesstable to theDepartmentIDproperty of theDepartmententity.Set both
Endattributes of the associationFK_DeptEngineering_DeptBusinessto0..1.Map the
DeptEngineering.DepartmentIDof the associationFK_DeptEngineering_DepartmentBusinessto theEngineeringDeptIDcolumn.Map the
DeptBusiness.DepartmentIDof the associationFK_DeptEngineering_DeptBusinessto theRelatedBusinessDeptcolumn.
The following complete edmx file contains the storage schema, the conceptual schema, and the mapping specification for the associations with derived types that are implemented in this topic.
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0" xmlns:edmx="https://schemas.microsoft.com/ado/2007/06/edmx">
<!-- EF Runtime content -->
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="SchoolDataModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns:store="https://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="https://schemas.microsoft.com/ado/2006/04/edm/ssdl">
<EntityContainer Name="SchoolDataModelStoreContainer">
<EntitySet Name="Department" EntityType="SchoolDataModel.Store.Department" store:Type="Tables" Schema="dbo" />
<EntitySet Name="DeptBusiness" EntityType="SchoolDataModel.Store.DeptBusiness" store:Type="Tables" Schema="dbo" />
<EntitySet Name="DeptEngineering" EntityType="SchoolDataModel.Store.DeptEngineering" store:Type="Tables" Schema="dbo" />
<EntitySet Name="Person" EntityType="SchoolDataModel.Store.Person" store:Type="Tables" Schema="dbo" />
<AssociationSet Name="FK_Department_Administrator" Association="SchoolDataModel.Store.FK_Department_Administrator">
<End Role="Person" EntitySet="Person" />
<End Role="Department" EntitySet="Department" />
</AssociationSet>
<AssociationSet Name="FK_DeptEngineering_DeptBusiness" Association="SchoolDataModel.Store.FK_DeptEngineering_DeptBusiness">
<End Role="DeptBusiness" EntitySet="DeptBusiness" />
<End Role="DeptEngineering" EntitySet="DeptEngineering" />
</AssociationSet>
</EntityContainer>
<EntityType Name="Department">
<Key>
<PropertyRef Name="DepartmentID" />
</Key>
<Property Name="DepartmentID" Type="int" Nullable="false" />
<Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="50" />
<Property Name="Budget" Type="money" Nullable="false" />
<Property Name="StartDate" Type="datetime" Nullable="false" />
<Property Name="Administrator" Type="int" />
</EntityType>
<EntityType Name="DeptBusiness">
<Key>
<PropertyRef Name="BusinessDeptID" />
</Key>
<Property Name="BusinessDeptID" Type="int" Nullable="false" />
<Property Name="LegalBudget" Type="money" Nullable="false" />
<Property Name="AccountingBudget" Type="money" Nullable="false" />
</EntityType>
<EntityType Name="DeptEngineering">
<Key>
<PropertyRef Name="EngineeringDeptID" />
</Key>
<Property Name="EngineeringDeptID" Type="int" Nullable="false" />
<Property Name="FiberOpticsBudget" Type="money" Nullable="false" />
<Property Name="LabBudget" Type="money" Nullable="false" />
<Property Name="RelatedBusinessDept" Type="int" />
</EntityType>
<EntityType Name="Person">
<Key>
<PropertyRef Name="PersonID" />
</Key>
<Property Name="PersonID" Type="int" Nullable="false" />
<Property Name="FirstName" Type="nvarchar" Nullable="false" MaxLength="50" />
<Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="50" />
<Property Name="HireDate" Type="datetime" />
<Property Name="EnrollmentDate" Type="datetime" />
<Property Name="PersonCategory" Type="smallint" Nullable="false" />
<Property Name="AdminDate" Type="datetime" />
</EntityType>
<Association Name="FK_Department_Administrator">
<End Role="Person" Type="SchoolDataModel.Store.Person" Multiplicity="0..1" />
<End Role="Department" Type="SchoolDataModel.Store.Department" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Person">
<PropertyRef Name="PersonID" />
</Principal>
<Dependent Role="Department">
<PropertyRef Name="Administrator" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_DeptEngineering_DeptBusiness">
<End Role="DeptBusiness" Type="SchoolDataModel.Store.DeptBusiness" Multiplicity="0..1" />
<End Role="DeptEngineering" Type="SchoolDataModel.Store.DeptEngineering" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="DeptBusiness">
<PropertyRef Name="BusinessDeptID" />
</Principal>
<Dependent Role="DeptEngineering">
<PropertyRef Name="RelatedBusinessDept" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema>
</edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="SchoolDataModel" Alias="Self" xmlns="https://schemas.microsoft.com/ado/2006/04/edm">
<EntityContainer Name="SchoolDataEntities">
<EntitySet Name="Departments" EntityType="SchoolDataModel.Department" />
<EntitySet Name="People" EntityType="SchoolDataModel.Person" />
<AssociationSet Name="FK_DeptEngineering_DeptBusiness" Association="SchoolDataModel.FK_DeptEngineering_DeptBusiness">
<End Role="DeptBusiness" EntitySet="Departments" />
<End Role="DeptEngineering" EntitySet="Departments" />
</AssociationSet>
<AssociationSet Name="DepartmentAdministrator" Association="SchoolDataModel.DepartmentAdministrator">
<End Role="Administrator" EntitySet="People" />
<End Role="Department" EntitySet="Departments" />
</AssociationSet>
</EntityContainer>
<EntityType Name="Department">
<Key>
<PropertyRef Name="DepartmentID" />
</Key>
<Property Name="DepartmentID" Type="Int32" Nullable="false" />
<Property Name="Name" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
<Property Name="Budget" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="StartDate" Type="DateTime" Nullable="false" />
<NavigationProperty Name="Administrator" Relationship="SchoolDataModel.DepartmentAdministrator" FromRole="Department" ToRole="Administrator" />
</EntityType>
<EntityType Name="DeptBusiness" BaseType="SchoolDataModel.Department">
<Property Name="LegalBudget" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="AccountingBudget" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<NavigationProperty Name="DeptEngineering" Relationship="SchoolDataModel.FK_DeptEngineering_DeptBusiness" FromRole="DeptBusiness" ToRole="DeptEngineering" />
</EntityType>
<EntityType Name="DeptEngineering" BaseType="SchoolDataModel.Department">
<Property Name="FiberOpticsBudget" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<Property Name="LabBudget" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
<NavigationProperty Name="DeptBusiness" Relationship="SchoolDataModel.FK_DeptEngineering_DeptBusiness" FromRole="DeptEngineering" ToRole="DeptBusiness" />
</EntityType>
<EntityType Name="Person">
<Key>
<PropertyRef Name="PersonID" />
</Key>
<Property Name="PersonID" Type="Int32" Nullable="false" />
<Property Name="FirstName" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
<Property Name="LastName" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
<Property Name="HireDate" Type="DateTime" />
<Property Name="EnrollmentDate" Type="DateTime" />
<Property Name="PersonCategory" Type="Int16" Nullable="false" />
</EntityType>
<Association Name="FK_DeptEngineering_DeptBusiness">
<End Role="DeptBusiness" Type="SchoolDataModel.DeptBusiness" Multiplicity="0..1" />
<End Role="DeptEngineering" Type="SchoolDataModel.DeptEngineering" Multiplicity="0..1" />
</Association>
<EntityType Name="Administrator" BaseType="SchoolDataModel.Person" >
<Property Name="AdminDate" Type="DateTime" Nullable="false" />
<NavigationProperty Name="Department" Relationship="SchoolDataModel.DepartmentAdministrator" FromRole="Administrator" ToRole="Department" />
</EntityType>
<Association Name="DepartmentAdministrator">
<End Type="SchoolDataModel.Administrator" Role="Administrator" Multiplicity="1" />
<End Type="SchoolDataModel.Department" Role="Department" Multiplicity="1" />
</Association>
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
<EntityContainerMapping StorageEntityContainer="SchoolDataModelStoreContainer" CdmEntityContainer="SchoolDataEntities">
<EntitySetMapping Name="Departments">
<EntityTypeMapping TypeName="IsTypeOf(SchoolDataModel.Department)">
<MappingFragment StoreEntitySet="Department">
<ScalarProperty Name="DepartmentID" ColumnName="DepartmentID" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="Budget" ColumnName="Budget" />
<ScalarProperty Name="StartDate" ColumnName="StartDate" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(SchoolDataModel.DeptEngineering)">
<MappingFragment StoreEntitySet="DeptEngineering">
<ScalarProperty Name="DepartmentID" ColumnName="EngineeringDeptID" />
<ScalarProperty Name="FiberOpticsBudget" ColumnName="FiberOpticsBudget" />
<ScalarProperty Name="LabBudget" ColumnName="LabBudget" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(SchoolDataModel.DeptBusiness)">
<MappingFragment StoreEntitySet="DeptBusiness">
<ScalarProperty Name="DepartmentID" ColumnName="BusinessDeptID" />
<ScalarProperty Name="LegalBudget" ColumnName="LegalBudget" />
<ScalarProperty Name="AccountingBudget" ColumnName="AccountingBudget" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="People">
<EntityTypeMapping TypeName="IsTypeOf(SchoolDataModel.Person)">
<MappingFragment StoreEntitySet="Person">
<ScalarProperty Name="PersonID" ColumnName="PersonID" />
<ScalarProperty Name="FirstName" ColumnName="FirstName" />
<ScalarProperty Name="LastName" ColumnName="LastName" />
<ScalarProperty Name="HireDate" ColumnName="HireDate" />
<ScalarProperty Name="EnrollmentDate" ColumnName="EnrollmentDate" />
<ScalarProperty Name="PersonCategory" ColumnName="PersonCategory" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(SchoolDataModel.Administrator)">
<MappingFragment StoreEntitySet="Person">
<ScalarProperty Name="PersonID" ColumnName="PersonID" />
<ScalarProperty Name="AdminDate" ColumnName="AdminDate" />
<Condition ColumnName="AdminDate" IsNull="false" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<AssociationSetMapping Name="DepartmentAdministrator" TypeName="SchoolDataModel.DepartmentAdministrator" StoreEntitySet="Department">
<EndProperty Name="Administrator">
<ScalarProperty Name="PersonID" ColumnName="Administrator" />
</EndProperty>
<EndProperty Name="Department">
<ScalarProperty Name="DepartmentID" ColumnName="DepartmentID" />
</EndProperty>
</AssociationSetMapping>
<AssociationSetMapping Name="FK_DeptEngineering_DeptBusiness" TypeName="SchoolDataModel.FK_DeptEngineering_DeptBusiness" StoreEntitySet="DeptEngineering" >
<EndProperty Name="DeptBusiness">
<ScalarProperty Name="DepartmentID" ColumnName="RelatedBusinessDept" />
</EndProperty>
<EndProperty Name="DeptEngineering">
<ScalarProperty Name="DepartmentID" ColumnName="EngineeringDeptID" />
</EndProperty>
<Condition ColumnName="RelatedBusinessDept" IsNull="false" />
</AssociationSetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
</edmx:Runtime>
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
<edmx:Designer xmlns="https://schemas.microsoft.com/ado/2007/06/edmx">
<edmx:Connection>
<DesignerInfoPropertySet>
<DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
</DesignerInfoPropertySet>
</edmx:Connection>
<edmx:Options>
<DesignerInfoPropertySet>
<DesignerProperty Name="ValidateOnBuild" Value="true" />
</DesignerInfoPropertySet>
</edmx:Options>
<!-- Diagram content (shape and connector positions) -->
<edmx:Diagrams>
<Diagram Name="SchoolData">
<EntityTypeShape EntityType="SchoolDataModel.Department" Width="1.5" PointX="3" PointY="1.125" Height="1.7566536458333335" IsExpanded="true" />
<EntityTypeShape EntityType="SchoolDataModel.DeptBusiness" Width="1.5" PointX="7.375" PointY="3.875" Height="1.4279589843749996" IsExpanded="true" />
<EntityTypeShape EntityType="SchoolDataModel.DeptEngineering" Width="1.5" PointX="5" PointY="3.875" Height="1.4279589843749996" IsExpanded="true" />
<EntityTypeShape EntityType="SchoolDataModel.Person" Width="1.5" PointX="0.75" PointY="0.875" Height="2.085348307291667" IsExpanded="true" />
<AssociationConnector Association="SchoolDataModel.FK_DeptEngineering_DeptBusiness" ManuallyRouted="false">
<ConnectorPoint PointX="7.375" PointY="4.5889794921875" />
<ConnectorPoint PointX="6.5" PointY="4.5889794921875" />
</AssociationConnector>
<EntityTypeShape EntityType="SchoolDataModel.Administrator" Width="1.5" PointX="0.5" PointY="4.5" Height="0.9349169921875" />
<InheritanceConnector EntityType="SchoolDataModel.Administrator">
<ConnectorPoint PointX="1.375" PointY="2.960348307291667" />
<ConnectorPoint PointX="1.375" PointY="4.5" />
</InheritanceConnector>
<AssociationConnector Association="SchoolDataModel.DepartmentAdministrator">
<ConnectorPoint PointX="2" PointY="5.1318058268229167" />
<ConnectorPoint PointX="3.75" PointY="5.1318058268229167" />
<ConnectorPoint PointX="3.75" PointY="2.8816536458333339" />
</AssociationConnector>
</Diagram>
</edmx:Diagrams>
</edmx:Designer>
</edmx:Edmx>
Example
The following application code is used to display and create instances of the associations with derived types that are implemented in this topic. The first segment of code creates new people and departments. Then a foreach loop reads departments and associations and displays their data. The code inside the if conditional statement only creates a new instance of the association between the derived types DeptEngineering and DeptBusiness if an instance of the association does not already exist in storage.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
namespace DerivedTypesAssociations
{
class Program
{
static void Main(string[] args)
{
string[] firstNames = { "François", "Syed", "Erik", "Michael", "James",
"Mark", "Satomi", "Phyllis", "Andreas", "Kari"};
string[] lastNames = { "Ajenstat", "Abbas", "Andersen", "Allen", "Alvord",
"Hassall", "Hayakawa", "Harris", "Hauser", "Hensien" };
try
{
using (SchoolDataEntities objCtx = new SchoolDataEntities())
{
int count1Depts = 0;
foreach (Department d in objCtx.Departments)
count1Depts++;
for(int i=count1Depts; i < 9; i++)
{
DeptEngineering newEngDept = new DeptEngineering();
newEngDept.DepartmentID = i + 1;
newEngDept.FiberOpticsBudget = 6000.00M;
newEngDept.LabBudget = 12000.00M;
newEngDept.Budget = newEngDept.FiberOpticsBudget +
newEngDept.LabBudget;
newEngDept.Name = "Engineering Dept " +
newEngDept.DepartmentID.ToString();
newEngDept.StartDate = DateTime.Now;
Administrator newAdmin1 = new Administrator();
newAdmin1.AdminDate = DateTime.Now;
newAdmin1.FirstName = firstNames[i];
newAdmin1.LastName = lastNames[i];
newAdmin1.PersonCategory = 3;
int count1People = 0;
foreach (Person p in objCtx.People)
count1People++;
newAdmin1.PersonID = count1People + 1;
objCtx.AddToPeople(newAdmin1);
newEngDept.Administrator = newAdmin1;
objCtx.AddToDepartments(newEngDept);
objCtx.SaveChanges();
}
foreach (DeptEngineering dept in
objCtx.Departments.OfType<DeptEngineering>())
{
Console.WriteLine(dept.Name);
dept.AdministratorReference.Load();
if (dept.Administrator != null)
Console.WriteLine("\tAdministrator: " +
dept.Administrator.LastName);
dept.DeptBusinessReference.Load();
if (dept.DeptBusiness != null)
{
dept.DeptBusiness.AdministratorReference.Load();
Console.WriteLine("\tRelated Business School: " +
dept.DeptBusiness.DepartmentID +
"Business School Administrator: " +
dept.DeptBusiness.Administrator.LastName);
}
}
DeptEngineering departmentToLink;
ObjectParameter deptParam = new ObjectParameter("p", 5);
if (objCtx.Departments.OfType<DeptEngineering>().Where(
"it.DepartmentID = @p", deptParam).Any<DeptEngineering>())
{
departmentToLink =
objCtx.Departments.OfType<DeptEngineering>().
Where("it.DepartmentID = @p", deptParam).First<DeptEngineering>();
if (departmentToLink != null)
departmentToLink.DeptBusinessReference.Load();
if (departmentToLink.DeptBusiness == null)
{
DeptBusiness newDeptBusiness = new DeptBusiness();
int countDepts = 0;
foreach (Department d in objCtx.Departments)
countDepts++;
newDeptBusiness.DepartmentID = countDepts + 1;
newDeptBusiness.AccountingBudget = 5000.00M;
newDeptBusiness.LegalBudget = 18000.00M;
newDeptBusiness.Name = "Business Department Id: " +
newDeptBusiness.DepartmentID;
newDeptBusiness.Budget = newDeptBusiness.AccountingBudget +
newDeptBusiness.LegalBudget;
newDeptBusiness.StartDate = DateTime.Now;
Administrator newAdmin = new Administrator();
newAdmin.AdminDate = DateTime.Now;
newAdmin.FirstName = "Sagiv";
newAdmin.LastName = "Hadaya";
newAdmin.PersonCategory = 3;
int countPeople = 0;
foreach (Person p in objCtx.People)
countPeople++;
newAdmin.PersonID = countPeople + 1;
objCtx.AddToPeople(newAdmin);
newDeptBusiness.Administrator = newAdmin;
objCtx.AddToDepartments(newDeptBusiness);
objCtx.SaveChanges();
departmentToLink.DeptBusiness = newDeptBusiness;
objCtx.SaveChanges();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException.ToString());
}
}
}
}
See Also
Tasks
How to: Define a Model with Table-per-Type Inheritance (Entity Framework)
How to: Define a Model with Table-per-Hierarchy Inheritance (Entity Framework)