views:

391

answers:

1

Say I have the following table definitions in SQL Server 2008:

CREATE TABLE Person
(PersonId INT IDENTITY NOT NULL PRIMARY KEY,
 Name VARCHAR(50) NOT NULL,
 ManyMoreIrrelevantColumns VARCHAR(MAX) NOT NULL)

CREATE TABLE Model
(ModelId INT IDENTITY NOT NULL PRIMARY KEY,
 ModelName VARCHAR(50) NOT NULL,
 Description VARCHAR(200) NULL)

CREATE TABLE ModelScore
(ModelId INT NOT NULL REFERENCES Model (ModelId),
 Score INT NOT NULL,
 Definition VARCHAR(100) NULL,
 PRIMARY KEY (ModelId, Score))

CREATE TABLE PersonModelScore
(PersonId INT NOT NULL REFERENCES Person (PersonId),
 ModelId INT NOT NULL,
 Score INT NOT NULL,
 PRIMARY KEY (PersonId, ModelId),
 FOREIGN KEY (ModelId, Score) REFERENCES ModelScore (ModelId, Score))

The idea here is that each Person may have only one ModelScore per Model, but each Person may have a score for any number of defined Models. As far as I can tell, this SQL should enforce these constraints naturally. The ModelScore has a particular "meaning," which is contained in the Definition. Nothing earth-shattering there.

Now, I try translating this into Entity Framework using the designer. After updating the model from the database and doing some editing, I have a Person object, a Model object, and a ModelScore object. PersonModelScore, being a join table, is not an object but rather is included as an association with some other name (let's say ModelScorePersonAssociation). The mapping details for the association are as follows:

- Association
  - Maps to PersonModelScore
    - ModelScore
        ModelId : Int32       <=>  ModelId : int
        Score : Int32         <=>  Score : int
    - Person
        PersonId : Int32      <=>  PersonId : int

On the right-hand side, the ModelId and PersonId values have primary key symbols, but the Score value does not.

Upon compilation, I get:

Error 3002: Problem in Mapping Fragment starting at line 5190: Potential runtime violation of table PersonModelScore's keys (PersonModelScore.ModelId, PersonModelScore.PersonId): Columns (PersonModelScore.PersonId, PersonModelScore.ModelId) are mapped to EntitySet ModelScorePersonAssociation's properties (ModelScorePersonAssociation.Person.PersonId, ModelScorePersonAssociation.ModelScore.ModelId) on the conceptual side but they do not form the EntitySet's key properties (ModelScorePersonAssociation.ModelScore.ModelId, ModelScorePersonAssociation.ModelScore.Score, ModelScorePersonAssociation.Person.PersonId).

What have I done wrong in the designer or otherwise, and how can I fix the error?

Many thanks!

+1  A: 

You should create a single Identity key for each table.

ModelScore should have a ModelScoreId, PersonModelScore should have a PersonModelScoreId.

References between table should be a single field.

Shiraz Bhaiji
Thank you for your suggestions. Now, how does this solution still preserve the integrity of the data model? Each Person is associated with no more than one of each Model, and the ModelScore must be a valid ModelScore for that Model. So, I think PersonModelScore would either have to have both a ModelId and a ModelScoreId, which is redundant and requires verification, or just have ModelScoreId, which requires verification that there are not multiple ModelScores per Model per Person. Neither way seems to work very well, in my opinion.Is this just a limitation of Entity Framework, then?
Andrew