实体框架 - 未分配已加载实体的 ID

发布于 2024-11-08 01:44:52 字数 6386 浏览 0 评论 0原文

我有以下 POCO 类:

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; }
}

这是相应的 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>

当我使用代码加载一个实体(目前数据库中只有一行)时:

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

我发现返回的 Person 对象的 Id 属性为 0 (数据库中为 1)。有人知道为什么它似乎没有设置吗?

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仅此而已 2024-11-15 01:44:52

好吧,这不是继承的问题,正如我最初想象的那样 - 继承会起作用。这很可能是两个问题的组合:

  • Id 在数据库中生成,但 EF 不知道它们。 EDMX 的 SSDL 和 CSDL 部分均应 使用 StoreGeneratePattern.Identity 定义 Id。这将强制 EF 在插入实体时重新加载 Id。
  • 我相信您正在使用相同的上下文实例来保存实体并调用查询。现在您遇到了身份映射模式。尽管从查询中检索到的数据 EF 将使用内部存储在其每个上下文缓存中的实例。由于第一个问题,缓存实例的 Id 的默认 int 值 = 0。

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文