我刚开始学习EF。我面临的问题是TPH。以下示例来自apress的EF食谱。该表基本上是这样的:
CREATE TABLE [Chapter2].[Employee](
[EmployeeId] [int] IDENTITY(1,1) NOT NULL,
[EmployeeType] [int] NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[Salary] [decimal](18, 0) NOT NULL,
[Wage] [decimal](18, 0) NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[EmployeeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
创建表格并将其导入EF后。我创建了两个实体,一个是FullTimeEmployee,另一个是HourlyEmployee。我将员工类型下的条件设置为1,全时为1,2为小时。我当然是从主Employee实体中删除该属性。
<edmx:Mappings>
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
<EntityContainerMapping StorageEntityContainer="EFRecipesModel1StoreContainer" CdmEntityContainer="EFRecipesEntities1">
<EntitySetMapping Name="Employees">
<EntityTypeMapping TypeName="IsTypeOf(EFRecipesModel1.Employee)">
<MappingFragment StoreEntitySet="Employee">
<ScalarProperty Name="EmployeeId" ColumnName="EmployeeId" />
<ScalarProperty Name="LastName" ColumnName="LastName" />
<ScalarProperty Name="FirstName" ColumnName="FirstName" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(EFRecipesModel1.FullTimeEmployee)">
<MappingFragment StoreEntitySet="Employee">
<ScalarProperty Name="EmployeeId" ColumnName="EmployeeId" />
<ScalarProperty Name="Salary" ColumnName="Salary" />
<Condition ColumnName="EmployeeType" Value="1" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(EFRecipesModel1.HourlyEmployee)">
<MappingFragment StoreEntitySet="Employee">
<ScalarProperty Name="EmployeeId" ColumnName="EmployeeId" />
<ScalarProperty Name="Wage" ColumnName="Wage" />
<Condition ColumnName="EmployeeType" Value="2" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
我得到的错误是:
错误3023:从第51行开始的mapping片段出现问题:必须映射表Employee中的Employee.Salary。它没有默认值,也不可为空。
我阅读并看到了一个建议更新SSDL,这在某种程度上对我没有意义:
<edmx:StorageModels>
<Schema Namespace="EFRecipesModel1.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2012" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityType Name="Employee">
<Key>
<PropertyRef Name="EmployeeId" />
</Key>
<Property Name="EmployeeId" Type="int" StoreGeneratedPattern="Identity" Nullable="false" />
<Property Name="EmployeeType" Type="int" Nullable ="false" DefaultValue="1"/>
<Property Name="FirstName" Type="nvarchar" MaxLength="50" Nullable="false" />
<Property Name="LastName" Type="nvarchar" MaxLength="50" Nullable="false" />
<Property Name="Salary" Type="decimal" Precision="18" Scale="0" Nullable="false" />
<Property Name="Wage" Type="decimal" Precision="18" Scale="0" Nullable="false" />
</EntityType>
<EntityContainer Name="EFRecipesModel1StoreContainer">
<EntitySet Name="Employee" EntityType="Self.Employee" Schema="Chapter2" store:Type="Tables" />
</EntityContainer>
</Schema>
</edmx:StorageModels>
请注意,我为EmployeeType添加了Nullable和Default值。这仍然没有解决问题。
我可以得到一些帮助,为什么我正确地映射这样的问题?
答案 0 :(得分:2)
对我来说,在商店模型中将DefaultValue添加到Salary
和Wage
更有意义:
<Property Name="Salary" Type="decimal" Nullable="false" DefaultValue="0"/>
<Property Name="Wage" Type="decimal" Nullable="false" DefaultValue="0"/>
还有概念模型(在edmx设计师中)。
将它们作为默认约束添加到数据库中的字段也是有意义的(尽管当从数据库生成模型时,EF不会将这些约束复制到edmx)。
无论如何,这些字段必须具有默认值,因为它们在数据库中不可为空,并且没有一个具体实体为这两个字段提供值。
答案 1 :(得分:0)
我遇到了类似的问题,我做的是;
右键单击&#34; Main&#34;实体,然后选择属性。将Abstract属性设置为true,标记&#34; Main&#34;实体为抽象。
以为我会分享这个,因为设置一个默认值让我停止了抱怨,但是在我的程序中需要时该值不可用。