Поделиться через


Как определить модель с несколькими наборами сущностей на тип (платформа Entity Framework)

Модель EDM позволяет включать тип сущности в несколько наборов сущностей в пределах одного контейнера сущностей или включать тип сущности в наборы сущностей в нескольких контейнерах сущностей. Определение нескольких наборов сущностей на тип (MEST) позволяет пользователям упростить код, когда к базам данных применено секционирование, а также в других подобных ситуациях, когда несколько таблиц имеют одну и ту же структуру. Дополнительные сведения см. в разделе Наборы сущностей (модель EDM).

Реализация концептуальной схемы для модели данных MEST

  1. Создайте проект библиотеки классов и добавьте к нему новый шаблон модели EDM.

  2. Реализуйте тип сущности Customer, который включен в два набора сущностей: один — для клиентов в Восточном регионе CustomersEast и второй — для клиентов в Западном регионе CustomersWest.

  3. Следует отметить различия между отдельным типом сущности Customer, используемым в двух региональных наборах сущностей клиентов, и двумя другими типами заказов — OrderEast и OrderWest в наборах сущностей OrdersEast и OrdersWest.

  4. Чтобы отразить структуру MEST, реализуйте ассоциации между отдельным типом Customer и двумя региональными типами заказов — OrderEast и OrderWest. В обеих ассоциациях между типом Customer и региональными типами заказов задайте Customer в элементе ассоциации с числом элементов, равным 1.

  5. Реализуйте два набора сущностей, содержащих тип Customer в CSDL-схеме. Наборы сущностей CustomersEast и CustomersWest указывают в качестве своего типа сущности RegionalCustomersModel.Customer.

<?xml version="1.0" encoding="utf-8"?>
<Schema Namespace="RegionalCustomersModel"
              Alias="Self"
              xmlns="https://schemas.microsoft.com/ado/2006/04/edm">

        <EntityContainer Name="RegionalCustomersEntities">

          <EntitySet Name="CustomersEast" 
                     EntityType="RegionalCustomersModel.Customer" />
          <EntitySet Name="CustomersWest" 
                     EntityType="RegionalCustomersModel.Customer" />
          <EntitySet Name="OrdersEast" 
                     EntityType="RegionalCustomersModel.OrderEast" />
          <EntitySet Name="OrdersWest" 
                     EntityType="RegionalCustomersModel.OrderWest" />

          <AssociationSet Name="FK_OrderEast_Customer"
                 Association="RegionalCustomersModel.FK_OrderEast_Customer">
            <End Role="Customer" EntitySet="CustomersEast" />
            <End Role="OrderEast" EntitySet="OrdersEast" />
          </AssociationSet>

          <AssociationSet Name="FK_OrderWest_Customer"
                 Association="RegionalCustomersModel.FK_OrderWest_Customer">
            <End Role="Customer" EntitySet="CustomersWest" />
            <End Role="OrderWest" EntitySet="OrdersWest" />
          </AssociationSet>

        </EntityContainer>

        <EntityType Name="Customer">
          <Key>
            <PropertyRef Name="CustomerId" />
          </Key>
          <Property Name="CustomerId" Type="Int32" Nullable="false" />
          <Property Name="Name" Type="String" Nullable="false" />
          <Property Name="TotalPurchases" Type="Decimal" Nullable="false" />

          <NavigationProperty Name="OrdersEast"
          Relationship="RegionalCustomersModel.FK_OrderEast_Customer"
          FromRole="Customer" ToRole="OrderEast" />

          <NavigationProperty Name="OrdersWest"
          Relationship="RegionalCustomersModel.FK_OrderWest_Customer"
          FromRole="Customer" ToRole="OrderWest" />
        </EntityType>

        <EntityType Name="OrderEast">
          <Key>
            <PropertyRef Name="OrderId" />
          </Key>
          <Property Name="OrderId" Type="Int32" Nullable="false" />
          <Property Name="OrderTotal"
                    Type="Decimal" Nullable="false" />
          <Property Name="Tax" Type="Decimal" />
          <NavigationProperty Name="Customer"
            Relationship="RegionalCustomersModel.FK_OrderEast_Customer"
              FromRole="OrderEast" ToRole="Customer" />
        </EntityType>

        <EntityType Name="OrderWest">
          <Key>
            <PropertyRef Name="OrderId" />
          </Key>
          <Property Name="OrderId" Type="Int32" Nullable="false" />
          <Property Name="OrderTotal" Type="Decimal" Nullable="false" />
          <Property Name="Tax" Type="Decimal" />
          <NavigationProperty Name="Customer"
            Relationship="RegionalCustomersModel.FK_OrderWest_Customer"
               FromRole="OrderWest" ToRole="Customer" />
        </EntityType>

        <Association Name="FK_OrderEast_Customer">
          <End Role="Customer"
               Type="RegionalCustomersModel.Customer" Multiplicity="1" />
          <End Role="OrderEast"
               Type="RegionalCustomersModel.OrderEast" Multiplicity="*" />
        </Association>

        <Association Name="FK_OrderWest_Customer">
          <End Role="Customer"
               Type="RegionalCustomersModel.Customer" Multiplicity="1" />
          <End Role="OrderWest"
               Type="RegionalCustomersModel.OrderWest" Multiplicity="*" />
        </Association>

      </Schema>

Реализация схемы хранения для модели данных MEST

  1. Реализуйте отдельные типы сущностей, соответствующие отдельным таблицам для наборов сущностей CustomerEast и CustomerWest.

  2. Следует заметить, что в схеме хранилища присутствуют две таблицы клиентов в отличие от концептуальной схемы, в которой существовал только один тип сущности Customer.

<?xml version="1.0" encoding="utf-8"?>
<Schema Namespace="RegionalCustomersModel.Store"
              Alias="Self"
              Provider="System.Data.SqlClient"
              ProviderManifestToken="2005"
             xmlns="https://schemas.microsoft.com/ado/2006/04/edm/ssdl">

        <EntityContainer Name="dbo">

          <EntitySet Name="CustomerEast"
             EntityType="RegionalCustomersModel.Store.CustomerEast" />
          <EntitySet Name="CustomerWest"
             EntityType="RegionalCustomersModel.Store.CustomerWest" />
          <EntitySet Name="OrderEast"
             EntityType="RegionalCustomersModel.Store.OrderEast" />
          <EntitySet Name="OrderWest"
             EntityType="RegionalCustomersModel.Store.OrderWest" />

          <AssociationSet Name="FK_OrderEast_CustomerEast"
           Association="RegionalCustomersModel.Store.FK_OrderEast_CustomerEast">
            <End Role="CustomerEast" EntitySet="CustomerEast" />
            <End Role="OrderEast" EntitySet="OrderEast" />
          </AssociationSet>

          <AssociationSet Name="FK_OrderWest_CustomerWest"
           Association="RegionalCustomersModel.Store.FK_OrderWest_CustomerWest">
            <End Role="CustomerWest" EntitySet="CustomerWest" />
            <End Role="OrderWest" EntitySet="OrderWest" />
          </AssociationSet>

        </EntityContainer>

        <EntityType Name="CustomerEast">
          <Key>
            <PropertyRef Name="CustomerId" />
          </Key>
          <Property Name="CustomerId" Type="int" Nullable="false" />
          <Property Name="Name" Type="nvarchar"
                    Nullable="false" MaxLength="50" />
          <Property Name="TotalPurchases" Type="money" Nullable="false" />
        </EntityType>

        <EntityType Name="CustomerWest">
          <Key>
            <PropertyRef Name="CustomerId" />
          </Key>
          <Property Name="CustomerId" Type="int" Nullable="false" />
          <Property Name="Name" Type="nvarchar"
                    Nullable="false" MaxLength="50" />
          <Property Name="TotalPurchases" Type="money" Nullable="false" />
        </EntityType>

        <EntityType Name="OrderEast">
          <Key>
            <PropertyRef Name="OrderId" />
          </Key>
          <Property Name="OrderId" Type="int" Nullable="false" />
          <Property Name="CustomerId" Type="int" Nullable="false" />
          <Property Name="OrderTotal" Type="money" Nullable="false" />
          <Property Name="Tax" Type="money" />
        </EntityType>

        <EntityType Name="OrderWest">
          <Key>
            <PropertyRef Name="OrderId" />
          </Key>
          <Property Name="OrderId" Type="int" Nullable="false" />
          <Property Name="CustomerId" Type="int" Nullable="false" />
          <Property Name="OrderTotal" Type="money" Nullable="false" />
          <Property Name="Tax" Type="money" />
        </EntityType>

        <Association Name="FK_OrderEast_CustomerEast">
          <End Role="CustomerEast"
           Type="RegionalCustomersModel.Store.CustomerEast" Multiplicity="1" />
          <End Role="OrderEast" Type="RegionalCustomersModel.Store.OrderEast"
               Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="CustomerEast">
              <PropertyRef Name="CustomerId" />
            </Principal>
            <Dependent Role="OrderEast">
              <PropertyRef Name="CustomerId" />
            </Dependent>
          </ReferentialConstraint>
        </Association>

        <Association Name="FK_OrderWest_CustomerWest">
          <End Role="CustomerWest"
            Type="RegionalCustomersModel.Store.CustomerWest"
               Multiplicity="1" />
          <End Role="OrderWest"
               Type="RegionalCustomersModel.Store.OrderWest"
               Multiplicity="*" />
          <ReferentialConstraint>
            <Principal Role="CustomerWest">
              <PropertyRef Name="CustomerId" />
            </Principal>
            <Dependent Role="OrderWest">
              <PropertyRef Name="CustomerId" />
            </Dependent>
          </ReferentialConstraint>
        </Association>

      </Schema>

Создание базы данных в среде SQL Server Management Studio

  1. Используйте следующий сценарий в среде SQL Server Management Studio, чтобы сформировать базу данных, используемую в данном примере и примере раздела Как задать модель с наследованием «таблица для типа» (платформа Entity Framework).

  2. Выберите в меню Файл пункт Создать, а затем пункт Запрос к компоненту Database Engine, чтобы создать базу данных SchoolData и схему с помощью среды SQL Server Management Studio.

  3. В диалоговом окне Подключение к компоненту Database Engine введите localhost или имя другого экземпляра SQL Server, а затем нажмите кнопку «Соединить».

  4. Вставьте следующий сценарий Transact-SQL в окно запроса и нажмите кнопку Выполнить.

USE [master]
GO
CREATE DATABASE [RegionalCustomersMEST] 
GO
USE [RegionalCustomersMEST]
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].[CustomerWest]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[CustomerWest](
     [CustomerId] [int] NOT NULL,
     [Name] [nvarchar](50) NOT NULL,
     [TotalPurchases] [money] NOT NULL,
 CONSTRAINT [PK_CustomerWest] PRIMARY KEY CLUSTERED 
(
     [CustomerId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) 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].[CustomerEast]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[CustomerEast](
     [CustomerId] [int] NOT NULL,
     [Name] [nvarchar](50) NOT NULL,
     [TotalPurchases] [money] NOT NULL,
 CONSTRAINT [PK_CustomerEast] PRIMARY KEY CLUSTERED 
(
     [CustomerId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) 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].[OrderWest]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[OrderWest](
     [OrderId] [int] NOT NULL,
     [CustomerId] [int] NOT NULL,
     [OrderTotal] [money] NOT NULL,
     [Tax] [money] NULL,
 CONSTRAINT [PK_OrderWest] PRIMARY KEY CLUSTERED 
(
     [OrderId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) 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].[OrderEast]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[OrderEast](
     [OrderId] [int] NOT NULL,
     [CustomerId] [int] NOT NULL,
     [OrderTotal] [money] NOT NULL,
     [Tax] [money] NULL,
 CONSTRAINT [PK_OrderEast] PRIMARY KEY CLUSTERED 
(
    [OrderId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_OrderWest_CustomerWest]') AND parent_object_id = OBJECT_ID(N'[dbo].[OrderWest]'))
ALTER TABLE [dbo].[OrderWest]  WITH CHECK ADD  CONSTRAINT [FK_OrderWest_CustomerWest] FOREIGN KEY([CustomerId])
REFERENCES [dbo].[CustomerWest] ([CustomerId])
GO
ALTER TABLE [dbo].[OrderWest] CHECK CONSTRAINT [FK_OrderWest_CustomerWest]
GO
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_OrderEast_CustomerEast]') AND parent_object_id = OBJECT_ID(N'[dbo].[OrderEast]'))
ALTER TABLE [dbo].[OrderEast]  WITH CHECK ADD  CONSTRAINT [FK_OrderEast_CustomerEast] FOREIGN KEY([CustomerId])
REFERENCES [dbo].[CustomerEast] ([CustomerId])
GO
ALTER TABLE [dbo].[OrderEast] CHECK CONSTRAINT [FK_OrderEast_CustomerEast]

Реализация спецификации сопоставления в модели MEST

  1. Сопоставьте одну сущность Customer с отдельными таблицами для наборов сущностей CustomerEast и CustomerWest, как это показано ниже.

  2. Следует отметить отдельные наборы сущностей для CustomersEast и CustomersWest в сопоставлении контейнеров сущностей.

<?xml version="1.0" encoding="utf-8"?>
<Mapping Space="C-S"
               xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">

        <EntityContainerMapping
          StorageEntityContainer="dbo"
          CdmEntityContainer="RegionalCustomersEntities">

          <EntitySetMapping Name="CustomersEast">
            <EntityTypeMapping TypeName="RegionalCustomersModel.Customer">
              <MappingFragment StoreEntitySet="CustomerEast">
                <ScalarProperty Name="CustomerId" ColumnName="CustomerId" />
                <ScalarProperty Name="Name" ColumnName="Name" />
                <ScalarProperty Name="TotalPurchases"
                                ColumnName="TotalPurchases" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>

          <EntitySetMapping Name="CustomersWest">
            <EntityTypeMapping TypeName="RegionalCustomersModel.Customer">
              <MappingFragment StoreEntitySet="CustomerWest">
                <ScalarProperty Name="CustomerId" ColumnName="CustomerId" />
                <ScalarProperty Name="Name" ColumnName="Name" />
                <ScalarProperty Name="TotalPurchases"
                                ColumnName="TotalPurchases" />
              </MappingFragment>
            </EntityTypeMapping>
          </EntitySetMapping>

          <EntitySetMapping Name="OrdersEast" StoreEntitySet="OrderEast"
                            TypeName="RegionalCustomersModel.OrderEast">
            <ScalarProperty Name="OrderId" ColumnName="OrderId" />
            <ScalarProperty Name="OrderTotal" ColumnName="OrderTotal" />
            <ScalarProperty Name="Tax" ColumnName="Tax" />
          </EntitySetMapping>

          <EntitySetMapping Name="OrdersWest" StoreEntitySet="OrderWest"
                            TypeName="RegionalCustomersModel.OrderWest">
            <ScalarProperty Name="OrderId" ColumnName="OrderId" />
            <ScalarProperty Name="OrderTotal" ColumnName="OrderTotal" />
            <ScalarProperty Name="Tax" ColumnName="Tax" />
          </EntitySetMapping>

          <AssociationSetMapping Name="FK_OrderEast_Customer"
                 TypeName="RegionalCustomersModel.FK_OrderEast_Customer"
                 StoreEntitySet="OrderEast">
            <EndProperty Name="Customer">
              <ScalarProperty Name="CustomerId" ColumnName="CustomerId" />
            </EndProperty>
            <EndProperty Name="OrderEast">
              <ScalarProperty Name="OrderId" ColumnName="OrderId" />
            </EndProperty>
            <Condition ColumnName="CustomerId" IsNull="false" />
          </AssociationSetMapping>

          <AssociationSetMapping Name="FK_OrderWest_Customer"
                 TypeName="RegionalCustomersModel.FK_OrderWest_Customer"
                 StoreEntitySet="OrderWest">
            <EndProperty Name="Customer">
              <ScalarProperty Name="CustomerId" ColumnName="CustomerId" />
            </EndProperty>
            <EndProperty Name="OrderWest">
              <ScalarProperty Name="OrderId" ColumnName="OrderId" />
            </EndProperty>
            <Condition ColumnName="CustomerId" IsNull="false" />
          </AssociationSetMapping>

        </EntityContainerMapping>

      </Mapping>

См. также

Задачи

Как создать и выполнить запрос объектов с использованием нескольких наборов сущностей на тип (платформа Entity Framework)
Как добавить объект к конкретному набору сущностей (платформа Entity Framework)