实体框架:在关联中使用非主要唯一键的替代解决方案

问题描述 投票:12回答:1

我知道实体框架工作不允许您使用非主要唯一密钥作为外键关联从数据库生成模型。我可以手动修改EDMX吗?如果是这样,有人可以给我一个例子或参考吗?如果没有,还有其他可能吗?

最简单的例子:

这是表格的DDL。你会注意到我有一个从PersonType.TypeCode到Person.TypeCode的外键

CREATE TABLE [dbo].[PersonType](
    [PersonTypeId] [int] NOT NULL,
    [TypeCode] [varchar](10) NOT NULL,
    [TypeDesc] [varchar](max) NULL,
 CONSTRAINT [PK_PersonType] PRIMARY KEY CLUSTERED 
 ([PersonTypeId] ASC)
 CONSTRAINT [UK_PersonType] UNIQUE NONCLUSTERED 
 ([TypeCode] ASC)
)

CREATE TABLE [dbo].[Person](
    [PersonId] [int] NOT NULL,
    [TypeCode] [varchar](10) NOT NULL,
 CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED 
 ([PersonId] ASC)
)

ALTER TABLE [dbo].[Person]  WITH CHECK ADD  CONSTRAINT [FK_Person_PersonType] FOREIGN KEY([TypeCode])
REFERENCES [dbo].[PersonType] ([TypeCode])

ALTER TABLE [dbo].[Person] CHECK CONSTRAINT [FK_Person_PersonType]

这是EDMX生成的

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
  <!-- EF Runtime content -->
  <edmx:Runtime>
    <!-- SSDL content -->
    <edmx:StorageModels>
      <Schema Namespace="testModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
        <EntityContainer Name="testModelStoreContainer">
          <EntitySet Name="Person" EntityType="testModel.Store.Person" store:Type="Tables" Schema="dbo" />
          <EntitySet Name="PersonType" EntityType="testModel.Store.PersonType" store:Type="Tables" Schema="dbo" />
        </EntityContainer>
        <EntityType Name="Person">
          <Key>
            <PropertyRef Name="PersonId" />
          </Key>
          <Property Name="PersonId" Type="int" Nullable="false" />
          <Property Name="TypeCode" Type="varchar" Nullable="false" MaxLength="10" />
        </EntityType>
        <!--Errors Found During Generation:
      warning 6035: The relationship 'FK_Person_PersonType' has columns that are not part of the key of the table on the primary side of the relationship. The relationship was excluded.
      -->
        <EntityType Name="PersonType">
          <Key>
            <PropertyRef Name="PersonTypeId" />
          </Key>
          <Property Name="PersonTypeId" Type="int" Nullable="false" />
          <Property Name="TypeCode" Type="varchar" Nullable="false" MaxLength="10" />
          <Property Name="TypeDesc" Type="varchar(max)" />
        </EntityType>
      </Schema>
    </edmx:StorageModels>
    <!-- CSDL content -->
    <edmx:ConceptualModels>
      <Schema Namespace="testModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
        <EntityContainer Name="testEntities">
          <EntitySet Name="People" EntityType="testModel.Person" />
          <EntitySet Name="PersonTypes" EntityType="testModel.PersonType" />
        </EntityContainer>
        <EntityType Name="Person">
          <Key>
            <PropertyRef Name="PersonId" />
          </Key>
          <Property Name="PersonId" Type="Int32" Nullable="false" />
          <Property Name="TypeCode" Type="String" Nullable="false" MaxLength="10" Unicode="false" FixedLength="false" />
        </EntityType>
        <EntityType Name="PersonType">
          <Key>
            <PropertyRef Name="PersonTypeId" />
          </Key>
          <Property Name="PersonTypeId" Type="Int32" Nullable="false" />
          <Property Name="TypeCode" Type="String" Nullable="false" MaxLength="10" Unicode="false" FixedLength="false" />
          <Property Name="TypeDesc" Type="String" MaxLength="Max" Unicode="false" FixedLength="false" />
        </EntityType>
      </Schema>
    </edmx:ConceptualModels>
    <!-- C-S mapping content -->
    <edmx:Mappings>
      <Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
        <EntityContainerMapping StorageEntityContainer="testModelStoreContainer" CdmEntityContainer="testEntities">
          <EntitySetMapping Name="People"><EntityTypeMapping TypeName="testModel.Person"><MappingFragment StoreEntitySet="Person">
            <ScalarProperty Name="PersonId" ColumnName="PersonId" />
            <ScalarProperty Name="TypeCode" ColumnName="TypeCode" />
          </MappingFragment></EntityTypeMapping></EntitySetMapping>
          <EntitySetMapping Name="PersonTypes"><EntityTypeMapping TypeName="testModel.PersonType"><MappingFragment StoreEntitySet="PersonType">
            <ScalarProperty Name="PersonTypeId" ColumnName="PersonTypeId" />
            <ScalarProperty Name="TypeCode" ColumnName="TypeCode" />
            <ScalarProperty Name="TypeDesc" ColumnName="TypeDesc" />
          </MappingFragment></EntityTypeMapping></EntitySetMapping>
        </EntityContainerMapping>
      </Mapping>
    </edmx:Mappings>
  </edmx:Runtime>

我试图修改EDMX以在personType和Person之间创建导航属性但是不成功。我只是想我可以手动创建关联的一些方法。任何帮助,将不胜感激。

c# visual-studio-2010 sql-server-2008 .net-4.0 entity-framework-4
1个回答
12
投票

不幸的是,到目前为止,没有办法在候选键上定义关联(即PersonType.TypeCode)。因为在EF(3.5和4.0)中,FK必须指向主键。 根据Alex Jameshis post here的说法,这是EF团队正在为下一个版本考虑的问题。

© www.soinside.com 2019 - 2024. All rights reserved.