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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实体框架:在关联中使用非主要唯一键的替代解决方案相关的知识,希望对你有一定的参考价值。

我知道实体框架工作不允许您使用非主要唯一密钥作为外键关联从数据库生成模型。我可以手动修改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之间创建导航属性但是不成功。我只是想我可以手动创建关联的一些方法。任何帮助,将不胜感激。

答案

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

以上是关于实体框架:在关联中使用非主要唯一键的替代解决方案的主要内容,如果未能解决你的问题,请参考以下文章

数据库主外键

数据库主外键

ASP.NET MVC 5 实体框架替代方案或在运行时指定架构的能力?

一对一关联映射

关联实体和非关联实体之间的连接,导致在 JPQL 中使用 Lazy fetch 生成非持久实体不断抛出 JpqlSyntaxException

oracle中 主键和外键是啥意思?啥地方采用呢?