事前に生成されたマッピングビューPre-generated mapping views

Entity Framework がクエリを実行したり、データソースへの変更を保存したりする前に、データベースにアクセスするための一連のマッピングビューを生成する必要があります。Before the Entity Framework can execute a query or save changes to the data source, it must generate a set of mapping views to access the database. これらのマッピングビューは、データベースを抽象的な方法で表す一連の Entity SQL ステートメントであり、アプリケーションドメインごとにキャッシュされるメタデータの一部です。These mapping views are a set of Entity SQL statement that represent the database in an abstract way, and are part of the metadata which is cached per application domain. 同じアプリケーションドメイン内に同じコンテキストの複数のインスタンスを作成すると、キャッシュされたメタデータからのマッピングビューが再生成されるのではなく再利用されます。If you create multiple instances of the same context in the same application domain, they will reuse mapping views from the cached metadata rather than regenerating them. マッピングビューの生成は最初のクエリの実行にかかる全体的なコストの重要な部分であるため、Entity Framework を使用すると、マッピングビューを事前に生成し、コンパイル済みのプロジェクトに含めることができます。Because mapping view generation is a significant part of the overall cost of executing the first query, the Entity Framework enables you to pre-generate mapping views and include them in the compiled project.詳細については、「  パフォーマンスに関する考慮事項 (Entity Framework)」を参照してください。 For more information, see  Performance Considerations (Entity Framework).

EF Power Tools Community Edition を使用したマッピングビューの生成Generating Mapping Views with the EF Power Tools Community Edition

ビューを事前に生成する最も簡単な方法は、 EF Power Tools Community エディションを使用することです。The easiest way to pre-generate views is to use the EF Power Tools Community Edition. パワーツールをインストールすると、次のように、ビューを生成するメニューオプションが表示されます。Once you have the Power Tools installed you will have a menu option to Generate Views, as below.

  • Code Firstモデルの場合は、dbcontext クラスを含むコードファイルを右クリックします。For Code First models right-click on the code file that contains your DbContext class.
  • EF デザイナーモデルの場合は、EDMX ファイルを右クリックします。For EF Designer models right-click on your EDMX file.

ビューの生成

プロセスが完了すると、次のようなクラスが生成されます。Once the process is finished you will have a class similar to the following generated

生成されたビュー

アプリケーションを実行すると、EF はこのクラスを使用して必要に応じてビューを読み込みます。Now when you run your application EF will use this class to load views as required. モデルが変更され、このクラスを再生成していない場合、EF は例外をスローします。If your model changes and you do not re-generate this class then EF will throw an exception.

コード EF6 からのマッピングビューの生成Generating Mapping Views from Code - EF6 Onwards

ビューを生成するもう1つの方法は、EF に用意されている Api を使用することです。The other way to generate views is to use the APIs that EF provides. この方法を使用する場合は、必要に応じてビューを自由にシリアル化できますが、自分でビューを読み込む必要もあります。When using this method you have the freedom to serialize the views however you like, but you also need to load the views yourself.

注意

EF6 以降のみ -このセクションに示されている api は Entity Framework 6 で導入されました。EF6 Onwards Only - The APIs shown in this section were introduced in Entity Framework 6. 以前のバージョンを使用している場合、この情報は適用されません。If you are using an earlier version this information does not apply.

ビューの生成Generating Views

ビューを生成するための Api は、StorageMappingItemCollection クラスに表示されます。The APIs to generate views are on the System.Data.Entity.Core.Mapping.StorageMappingItemCollection class. ObjectContext の MetadataWorkspace を使用して、コンテキストの StorageMappingCollection を取得できます。You can retrieve a StorageMappingCollection for a Context by using the MetadataWorkspace of an ObjectContext. 新しい DbContext API を使用している場合は、次のような IObjectContextAdapter を使用してこれにアクセスできます。このコードでは、dbContext という名前の派生 DbContext のインスタンスを使用しています。If you are using the newer DbContext API then you can access this by using the IObjectContextAdapter like below, in this code we have an instance of your derived DbContext called dbContext:

    var objectContext = ((IObjectContextAdapter) dbContext).ObjectContext;
    var  mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace
                                                                        .GetItemCollection(DataSpace.CSSpace);

StorageMappingItemCollection を取得すると、GenerateViews と ComputeMappingHashValue メソッドにアクセスできるようになります。Once you have the StorageMappingItemCollection then you can get access to the GenerateViews and ComputeMappingHashValue methods.

    public Dictionary\<EntitySetBase, DbMappingView> GenerateViews(IList<EdmSchemaError> errors)
    public string ComputeMappingHashValue()

最初のメソッドは、コンテナーマッピング内の各ビューのエントリを含むディクショナリを作成します。The first method creates a dictionary with an entry for each view in the container mapping. 2番目のメソッドは、1つのコンテナーマッピングのハッシュ値を計算し、ビューが事前に生成された後にモデルが変更されていないことを検証するために実行時に使用されます。The second method computes a hash value for the single container mapping and is used at runtime to validate that the model has not changed since the views were pre-generated. 複数のコンテナーマッピングが関係する複雑なシナリオでは、2つのメソッドのオーバーライドが提供されます。Overrides of the two methods are provided for complex scenarios involving multiple container mappings.

ビューを生成するときに、GenerateViews メソッドを呼び出し、結果として得られた EntitySetBase および DbMappingView を記述します。When generating views you will call the GenerateViews method and then write out the resulting EntitySetBase and DbMappingView. また、ComputeMappingHashValue メソッドによって生成されたハッシュも格納する必要があります。You will also need to store the hash generated by the ComputeMappingHashValue method.

ビューの読み込みLoading Views

GenerateViews メソッドによって生成されたビューを読み込むには、DbMappingViewCache 抽象クラスを継承するクラスを EF に提供します。In order to load the views generated by the GenerateViews method, you can provide EF with a class that inherits from the DbMappingViewCache abstract class. DbMappingViewCache は、実装する必要がある2つのメソッドを指定します。DbMappingViewCache specifies two methods that you must implement:

    public abstract string MappingHashValue { get; }
    public abstract DbMappingView GetView(EntitySetBase extent);

MappingHashValue プロパティは、ComputeMappingHashValue メソッドによって生成されたハッシュを返す必要があります。The MappingHashValue property must return the hash generated by the ComputeMappingHashValue method. EF がビューを要求するときに、最初に生成され、このプロパティによって返されるハッシュとモデルのハッシュ値を比較します。When EF is going to ask for views it will first generate and compare the hash value of the model with the hash returned by this property. 一致しない場合、EF は EntityCommandCompilationException 例外をスローします。If they do not match then EF will throw an EntityCommandCompilationException exception.

GetView メソッドは EntitySetBase を受け入れ、GenerateViews メソッドによって生成されたディクショナリ内の指定された EntitySetBase に関連付けられていた EntitySql を含む DbMappingVIew を返す必要があります。The GetView method will accept an EntitySetBase and you need to return a DbMappingVIew containing the EntitySql that was generated for that was associated with the given EntitySetBase in the dictionary generated by the GenerateViews method. EF が不要なビューを要求した場合、GetView は null を返す必要があります。If EF asks for a view that you do not have then GetView should return null.

次に示すのは、前述のようにパワーツールで生成された DbMappingViewCache からの抽出です。ここでは、必要な EntitySql を格納および取得するための1つの方法を示しています。The following is an extract from the DbMappingViewCache that is generated with the Power Tools as described above, in it we see one way to store and retrieve the EntitySql required.

    public override string MappingHashValue
    {
        get { return "a0b843f03dd29abee99789e190a6fb70ce8e93dc97945d437d9a58fb8e2afd2e"; }
    }

    public override DbMappingView GetView(EntitySetBase extent)
    {
        if (extent == null)
        {
            throw new ArgumentNullException("extent");
        }

        var extentName = extent.EntityContainer.Name + "." + extent.Name;

        if (extentName == "BlogContext.Blogs")
        {
            return GetView2();
        }

        if (extentName == "BlogContext.Posts")
        {
            return GetView3();
        }

        return null;
    }

    private static DbMappingView GetView2()
    {
        return new DbMappingView(@"
            SELECT VALUE -- Constructing Blogs
            [BlogApp.Models.Blog](T1.Blog_BlogId, T1.Blog_Test, T1.Blog_title, T1.Blog_Active, T1.Blog_SomeDecimal)
            FROM (
            SELECT
                T.BlogId AS Blog_BlogId,
                T.Test AS Blog_Test,
                T.title AS Blog_title,
                T.Active AS Blog_Active,
                T.SomeDecimal AS Blog_SomeDecimal,
                True AS _from0
            FROM CodeFirstDatabase.Blog AS T
            ) AS T1");
    }

EF で DbMappingViewCache を使用するには、DbMappingViewCacheTypeAttribute を使用して、作成されたコンテキストを指定します。To have EF use your DbMappingViewCache you add use the DbMappingViewCacheTypeAttribute, specifying the context that it was created for. 次のコードでは、ブログコンテキストを MyMappingViewCache クラスに関連付けます。In the code below we associate the BlogContext with the MyMappingViewCache class.

    [assembly: DbMappingViewCacheType(typeof(BlogContext), typeof(MyMappingViewCache))]

より複雑なシナリオでは、マッピングビューのキャッシュファクトリを指定することによって、マッピングビューのキャッシュインスタンスを指定できます。For more complex scenarios, mapping view cache instances can be provided by specifying a mapping view cache factory. これは、抽象クラスの system.object を実装することによって行うことができます。。This can be done by implementing the abstract class System.Data.Entity.Infrastructure.MappingViews.DbMappingViewCacheFactory. 使用されるマッピングビューのキャッシュファクトリのインスタンスは、StorageMappingItemCollection. MappingViewCacheFactoryproperty を使用して取得または設定できます。The instance of the mapping view cache factory that is used can be retrieved or set using the StorageMappingItemCollection.MappingViewCacheFactoryproperty.