2016-12-06 9 views
1

私は2つのテーブル:DataAdditionalDataを持っています。それらの関係は1対1である(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;} 
} 

これは正常に動作します:

メインコンテキストについては

私はクラスを持っています。私はビューにマップすることができます

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 

をしかし、私が知りたい:

私はちょうど DataAdditionalDataを有するか否かを、知っておく必要があり、別のコンテキストのために

ExtendedDataクラスを追加のビューなしでテーブルにマップできますか?あなただけの投影の結果としてExtendedDataを使用して、[OKであれば以下のようなクエリは、あなたが探しているものかもしれません

+0

はありません、第二文脈で私はちょうどチェックするために、AdditionalData'オブジェクトは(約1メガバイト)重いです 'と想像 – Backs

答えて

1

var result = ctx.Data.Select(d => new ExtendedData {Id = d.Id, Name = d.Name, HasAdditionalData = d.ApprovalStatus != null);

問題は、あなたのPKが再生されているということですFKと同じ二重課税でも、別のフィールドとしてAdditionalDataのFKを定義しました。おそらくAdditionalDataIdをNULLにして、おそらくAdditionalDataの存在を確認するのは簡単でしょう。 AdditionalDataIdがnullであるかどうかをチェックするだけで、パフォーマンスが向上します。

+0

を編集するための' AdditionalData'に耳を傾ける@GertArnoldそれがnullまたはnullではありませんFK(AdditionalDataIdプロパティ)をチェック – Backs

+0

@Backsは、オブジェクトをロードしません。レイジーローディングは、FK idプロパティにアクセスするだけではトリガーされません。 – Klinger

+0

ああ、私はあなたが何を意味するかを見ます。はい、私は追加の列 'AdditionalDataId'が一意の値を持っている場合、これは動作します。これは少し複雑なスキーマです。しかし、可能です、はい – Backs

1

DefiningQuery構成のデータベースビューの作成を避けることができます。 DefiningQueryは、データベースビューと同じ機能を提供しますが、データベース自体ではなく、モデルで定義されています。あなたががVisual StudioのモデルデザイナとDefiningQueryを作成することはできません

は、手動でEDMXファイルを編集する必要があります。あなたのビューのクエリがわずかな変化でDefiningQuery要素の下に指定されている

<!-- 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> 

注:最初にSSDL層へEntityTypeEntitySet定義を追加します。

次に、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> 

を次にあなたが再び手動でEDMXの編集や表のマッピングを通じて、CSDL-SSDLマッピングを追加する必要があります

<!-- 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> 

は注意してください:あなたのSSDLの一部で手動で変更モデルをデータベースから更新すると、edmxは失われます。それはDBからそれをロードするために非常に奇妙ですので

+0

興味深い解決策、edmx-file – Backs