0

I have the following POCO class:

public class Person : Entity
    {
        public string FirstName { get; set; }
        public string MiddleName1 { get; set; }
        public string MiddleName2 { get; set; }
        public string LastName { get; set; }
        public byte? DayOfBirth { get; set; }
        public byte? MonthOfBirth { get; set; }
        public Int16? YearOfBirth { get; set; }
        public string MobileNumber { get; set; }
    }

public abstract class Entity
{
    public int Id { get; set; }
}

Here is the corresponding edmx xml:

<edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
  <!-- EF Runtime content -->
  <edmx:Runtime>
    <!-- SSDL content -->
    <edmx:StorageModels>
      <Schema Namespace="EntityFramework.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/2009/02/edm/ssdl">
        <EntityContainer Name="EntityFrameworkStoreContainer">
          <EntitySet Name="People" EntityType="EntityFramework.Store.People" store:Type="Tables" Schema="dbo" />
        </EntityContainer>
        <EntityType Name="People">
          <Key>
            <PropertyRef Name="Id" />
          </Key>
          <Property Name="Id" Type="int" Nullable="false" />
          <Property Name="FirstName" Type="nvarchar" Nullable="false" MaxLength="50" />
          <Property Name="MiddleName1" Type="nvarchar" MaxLength="50" />
          <Property Name="MiddleName2" Type="nvarchar" MaxLength="50" />
          <Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="50" />
          <Property Name="DayOfBirth" Type="tinyint" />
          <Property Name="MonthOfBirth" Type="tinyint" />
          <Property Name="YearOfBirth" Type="smallint" />
          <Property Name="MobileNumber" Type="varchar" MaxLength="20" />
        </EntityType>
      </Schema>
    </edmx:StorageModels>
    <!-- CSDL content -->
    <edmx:ConceptualModels>
      <Schema Namespace="EntityFramework" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
        <EntityContainer Name="TheCleavesEntities" annotation:LazyLoadingEnabled="true">
          <EntitySet Name="People" EntityType="EntityFramework.Person" />
        </EntityContainer>
        <EntityType Name="Person">
          <Key>
            <PropertyRef Name="Id" />
          </Key>
          <Property Name="Id" Type="Int32" Nullable="false" />
          <Property Name="FirstName" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
          <Property Name="MiddleName1" Type="String" MaxLength="50" Unicode="true" FixedLength="false" />
          <Property Name="MiddleName2" Type="String" MaxLength="50" Unicode="true" FixedLength="false" />
          <Property Name="LastName" Type="String" Nullable="false" MaxLength="50" Unicode="true" FixedLength="false" />
          <Property Name="DayOfBirth" Type="Byte" Nullable="true" />
          <Property Name="MonthOfBirth" Type="Byte" Nullable="true" />
          <Property Name="YearOfBirth" Type="Int16" Nullable="true" />
          <Property Name="MobileNumber" Type="String" MaxLength="20" Unicode="false" FixedLength="false" />
        </EntityType>
      </Schema>
    </edmx:ConceptualModels>
    <!-- C-S mapping content -->
    <edmx:Mappings>
      <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
        <EntityContainerMapping StorageEntityContainer="EntityFrameworkStoreContainer" CdmEntityContainer="TheCleavesEntities">
          <EntitySetMapping Name="People"><EntityTypeMapping TypeName="EntityFramework.Person"><MappingFragment StoreEntitySet="People">
            <ScalarProperty Name="Id" ColumnName="Id" />
            <ScalarProperty Name="FirstName" ColumnName="FirstName" />
            <ScalarProperty Name="MiddleName1" ColumnName="MiddleName1" />
            <ScalarProperty Name="MiddleName2" ColumnName="MiddleName2" />
            <ScalarProperty Name="LastName" ColumnName="LastName" />
            <ScalarProperty Name="DayOfBirth" ColumnName="DayOfBirth" />
            <ScalarProperty Name="MonthOfBirth" ColumnName="MonthOfBirth" />
            <ScalarProperty Name="YearOfBirth" ColumnName="YearOfBirth" />
            <ScalarProperty Name="MobileNumber" ColumnName="MobileNumber" />
          </MappingFragment></EntityTypeMapping></EntitySetMapping>
        </EntityContainerMapping>
      </Mapping>
    </edmx:Mappings>
  </edmx:Runtime>
  <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
  <Designer xmlns="http://schemas.microsoft.com/ado/2008/10/edmx">
    <Connection>
      <DesignerInfoPropertySet>
        <DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
      </DesignerInfoPropertySet>
    </Connection>
    <Options>
      <DesignerInfoPropertySet>
        <DesignerProperty Name="ValidateOnBuild" Value="true" />
        <DesignerProperty Name="EnablePluralization" Value="True" />
        <DesignerProperty Name="IncludeForeignKeysInModel" Value="False" />
      </DesignerInfoPropertySet>
    </Options>
    <!-- Diagram content (shape and connector positions) -->
    <Diagrams>
      <Diagram Name="TheCleaves">
        <EntityTypeShape EntityType="EntityFramework.Person" Width="1.5" PointX="0.75" PointY="0.75" Height="2.7494921874999996" IsExpanded="true" />
      </Diagram>
    </Diagrams>
  </Designer>
</edmx:Edmx>

When I load up an entity (there's only one row in the database at present) with the code:

IEnumerable<Person> people = context.People.Where(x => true);

I'm finding that the Id property of the returned Person object is 0 (it's 1 in the database). Anyone have any idea why it appears not to be set?

Thanks

David
  • 14,678
  • 20
  • 80
  • 145
  • Are there any mappings corresponding to your Entity class? Are you expecting all Ids to be globally unique or unique for that type? i.e. if you have Person and Product, can there be a Product with Id of 1 and a Person with Id of 1? Are you wanting to use inheritance to share behaviour, or would an Interface do the job? (Entity Framework does things with inheritance that it doesn't with an interface) – RichardW1001 May 17 '11 at 08:15
  • Ids are only unique to the type. I'm using inheritance to share behaviour (it's also semantically sound - entities are a particular type of class). Do you think that the Id is not being populated because it's from a base class? – David May 17 '11 at 18:22

1 Answers1

2

Ok it is not problem with inheritance as I initially thought - the inheritance will work. This is most probably combination of two problems:

  • Id is generated in the database but EF doesn't know about them. Both SSDL and CSDL part of EDMX should define Id with StoreGeneratedPattern.Identity. This will force EF to reload Id when entity is inserted.
  • I believe you are using same context instance for saving entity and calling the query. Now you meet identity map pattern. Despite the data retrieved from the query EF will use instance internally stored in its per-context cache. Because of the first problem the cached instance has Id with default int value = 0.
Community
  • 1
  • 1
Ladislav Mrnka
  • 349,807
  • 56
  • 643
  • 654
  • Can this really be the case? I can't quite believe that EF would interfere so much with my domain design decisions. I use this pattern with NHibernate all the time, and NH doesn't even so much as raise an eyebrow. – David May 17 '11 at 18:25
  • When I change the class so that it doesn't extend Entity and add the Id property to the class directly, I still get exactly the same problem. – David May 17 '11 at 18:43
  • Are you using the same context instance for saving and loading? – Ladislav Mrnka May 17 '11 at 18:45
  • I'm not saving. This particular context instance is simply loading a list of Person instances for display in a list. – David May 18 '11 at 10:48
  • I like your thinking by the way, but the row has been in the database for ages, I'm now just trying to work out how to load it up! – David May 18 '11 at 10:50
  • I deleted and recreated the .edmx and it's all good now. Shame I nevre worked out what was wrong. – David May 26 '11 at 14:39