我有2个表:Data
和AdditionalData
。他们的关系是1到1-0(任何Data
可以有0或1 AdditionalData
)。
对于主要上下文,我有类:
class Data
{
public long Id {get;set;} // PK
public string Name {get;set;}
public AdditionalData AdditionalData {get;set;} // can be null
}
class AdditionalData
{
public long Id {get;set;} // PK
public string AdditionalName {get;set;}
}
这很好用。
对于我需要知道的另一个背景,Data
是否AdditionalData
:
class ExtendedData
{
public long Id {get;set;} //PK
public string Name {get;set;}
public bool HasAdditionalData {get;set;}
}
我可以将其映射到视图:
SELECT
d.*
,IIF(ad.Id IS NULL, 0, 1) AS HasAdditionalData
FROM Data AS d
LEFT OUTER JOIN AdditionalData AS ad ON d.Id = ad.Id
但我想知道:
我可以将ExtendedData
类映射到没有其他视图的表吗?
答案 0 :(得分:1)
如果您只是使用ExtendedData
作为投影结果,那么下面的查询可能就是您要查找的内容:
var result = ctx.Data.Select(d => new ExtendedData {Id = d.Id, Name = d.Name, HasAdditionalData = d.ApprovalStatus != null);
问题是你的PK正在扮演FK的双重职责,你是否将AdditionalData
的FK定义为另一个字段,可能为AdditionalDataId
,然后检查是否存在{{1}将是微不足道的;只检查AdditionalData
是否为空,您的性能也会提高。
答案 1 :(得分:1)
您可以避免使用DefiningQuery构造创建数据库视图。 DefiningQuery提供与数据库视图相同的功能,但它在模型中定义,而不是在数据库本身中定义。
您无法使用Visual Studio Model Designer创建DefiningQuery
,但您应手动编辑edmx文件。首先将EntityType
和EntitySet
定义添加到SSDL层:
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="TestDataModel.Store" Provider="System.Data.SqlClient" ProviderManifestToken="2012" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityType Name="ExtendedData">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="Name" Type="nvarchar(max)" Nullable="false" />
<Property Name="HasAdditionalData" Type="bit" Nullable="false" />
</EntityType>
<EntityContainer Name="TestDataModelStoreContainer">
<EntitySet Name="ExtendedData" EntityType="Self.ExtendedData" store:Type="Views" store:Schema="dbo" store:Name="ExtendedData">
<DefiningQuery>
SELECT d.Id, d.Name, CAST(IIF(ad.Id IS NULL, 0, 1) AS BIT) AS HasAdditionalData
FROM Data AS d
LEFT OUTER JOIN AdditionalData AS ad ON d.Id = ad.Id
</DefiningQuery>
</EntitySet>
</EntityContainer>
</Schema></edmx:StorageModels>
请注意,您的查看查询是在DefiningQuery
元素下指定的,稍作修改。
然后您应该将ExtendedData
实体添加到CSDL。这可以通过进一步手动编辑edmx或使用Model Designer来完成。这里最后看起来如何:
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="TestDataModel" Alias="Self" annotation:UseStrongSpatialTypes="false" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<EntityContainer Name="TestDataEntities2" annotation:LazyLoadingEnabled="true">
<EntitySet Name="ExtendedDatas" EntityType="TestDataModel.ExtendedData" />
</EntityContainer>
<EntityType Name="ExtendedData">
<Key>
<PropertyRef Name="Id" />
</Key>
<Property Name="Id" Type="Int64" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Name="Name" Type="String" Nullable="false" />
<Property Name="HasAdditionalData" Type="Boolean" Nullable="false" />
</EntityType>
</Schema>
</edmx:ConceptualModels>
然后你应该添加CSDL-SSDL映射,再次手动编辑edmx或通过表映射:
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
<EntityContainerMapping StorageEntityContainer="TestDataModelStoreContainer" CdmEntityContainer="TestDataEntities2">
<EntitySetMapping Name="ExtendedDatas">
<EntityTypeMapping TypeName="IsTypeOf(TestDataModel.ExtendedData)">
<MappingFragment StoreEntitySet="ExtendedData">
<ScalarProperty Name="HasAdditionalData" ColumnName="HasAdditionalData" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="Id" ColumnName="Id" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
注意:如果从数据库更新模型,则edmx的SSDL部分中的任何手动更改都将丢失。