11

Tôi biết công việc khung thực thể không cho phép bạn tạo mô hình từ cơ sở dữ liệu bằng cách sử dụng các khóa duy nhất không phải là khóa ngoại. Tôi có thể sửa đổi EDMX theo cách thủ công không? Nếu có, ai đó có thể cung cấp cho tôi một ví dụ hoặc tài liệu tham khảo? Nếu không, có khả năng nào khác không?Entity Framework: Giải pháp thay thế để sử dụng các khóa duy nhất không chính trong liên kết

Ví dụ dễ nhất:

Đây là DDL cho các bảng. Bạn sẽ nhận thấy tôi có một chính nước ngoài từ 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] 

Dưới đây là EDMX tạo

<?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> 

Tôi đã cố gắng để thay đổi EDMX để tạo ra các propery điều hướng giữa personType và Person nhưng không thành công. Tôi chỉ nghĩ rằng tôi có thể tạo ra các hiệp hội bằng tay một số cách. Bất kỳ trợ giúp sẽ được đánh giá cao.

+0

Tôi thực sự không hiểu lược đồ của bạn. Điều này trông giống như một '1-1' phải không? Một 'Person' có một' PersonType' cụ thể. Những gì tôi không hiểu là lý do tại sao bảng 'PersonType' có một trường được gọi là' PersonTypeId'. Nếu đây là một bảng tra cứu, bạn không nên có 'TypeCode' (PK), và' TypeDesc'? Và sau đó FK trên 'Person' thành' TypeCode' sẽ hoạt động tốt, vì nó là một PK. – RPM1984

+0

@ RPM1984 .. Ví dụ này chỉ là một ví dụ đơn giản. Nó không phải là một cái gì đó im sử dụng nhưng một cái gì đó để hiển thị các vấn đề. Về cơ bản, EF sẽ không cho phép bạn tạo mô hình bằng cách sử dụng các khóa duy nhất không chính. –

+0

Ok - nhưng tôi nghĩ EF đang làm điều đúng ở đây. Mặc dù trường là 'duy nhất', một FK nên tham chiếu đến PK, chứ không phải là Vương quốc Anh. – RPM1984

Trả lời

12

Thật không may là hiện tại không có cách nào để xác định liên kết trên khóa ứng cử viên (ví dụ: PersonType.TypeCode). bởi vì Trong EF (3.5 và 4.0) FK phải PHẢI trỏ đến các phím chính.

Theo Alex James từ his post here, đây là điều mà nhóm EF đang xem xét cho phiên bản tiếp theo.

+12

Bốn năm sau, vẫn không được hỗ trợ (( – AFD

+2

Nghiêm túc, làm thế nào để mọi người có thể sử dụng "doanh nghiệp" tripe.) LinqToSQL bị bỏ rơi (được khởi động tốt hơn ORM * *) và EF1 làm tốt hơn. đã được hứa hẹn - dường như vẫn thiếu nguyên tắc cơ bản * RA * – user2864740

+9

EF 6.1.2 (2015/02) vẫn không được hỗ trợ: ( –

Các vấn đề liên quan