代码之家  ›  专栏  ›  技术社区  ›  John Hartsock

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

  •  12
  • John Hartsock  · 技术社区  · 14 年前

    我知道实体框架不允许使用非主键作为外键关联从数据库生成模型。我可以手动修改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]
    

    <?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之间创建导航属性,但没有成功。我想我可以手动创建一个关联。任何帮助都将不胜感激。

    1 回复  |  直到 14 年前
        1
  •  14
  •   Community Romance    7 年前

    不幸的是,到目前为止还没有办法在候选密钥(即。 个人类型代码 在EF(3.5和4.0)中,FKs必须指向主键。

    根据 Alex James his post here ,这是EF团队正在考虑的下一个版本。