共用方式為


預先產生的對應檢視

在 Entity Framework 可以執行查詢或儲存資料來源的變更之前,它必須產生一組對應檢視來存取資料庫。 這些對應檢視是一組 Entity SQL 語句,以抽象方式表示資料庫,而且是每個應用程式域快取之中繼資料的一部分。 如果您在相同的應用程式域中建立相同內容的多個實例,它們會重複使用快取中繼資料中的對應檢視,而不是重新產生它們。 因為對應檢視產生是執行第一個查詢整體成本的重要部分,Entity Framework 可讓您預先產生對應檢視,並將其包含在編譯的專案中。 如需詳細資訊,請參閱 效能考慮(Entity Framework)。

使用 EF Power Tools Community Edition 產生對應檢視

預先產生檢視的最簡單方式是使用 EF Power Tools Community Edition 。 安裝 Power Tools 之後,您將有 [產生檢視] 的功能表選項,如下所示。

  • 針對 Code First 模型,以滑鼠右鍵按一下包含 DbCoNtext 類別的程式碼檔案。
  • 針對 EF Designer 模型,以滑鼠右鍵按一下您的 EDMX 檔案。

generate Views

程式完成之後,您將會有類似下列產生的類別

generated Views

現在當您執行應用程式 EF 時,會使用此類別視需要載入檢視。 如果您的模型變更,且您未重新產生此類別,EF 將會擲回例外狀況。

從程式碼產生對應檢視 - EF6 及更新版本

產生檢視的另一種方式是使用 EF 提供的 API。 使用此方法時,您可以隨意序列化檢視,但也需要自行載入檢視。

注意

僅限 EF6 及更新版本 - 本節中顯示的 API 是在 Entity Framework 6 中引進的。 如果您使用舊版,則不適用這項資訊。

產生檢視

要產生檢視的 API 位於 System.Data.Entity.Core.Mapping 上。儲存體MappingItemCollection 類別。 您可以使用 ObjectCoNtext 的 MetadataWorkspace 來擷取 CoNtext 的 儲存體MappingCollection。 如果您使用較新的 DbCoNtext API,則可以使用如下的 IObjectCoNtextAdapter 來存取此 API,在此程式碼中,我們有一個稱為 dbCoNtext 的衍生 DbCoNtext 實例:

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

取得 儲存體MappingItemCollection 之後,您就可以存取 GenerateViews 和 ComputeMappingHashValue 方法。

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

第一個方法會建立字典,其中包含容器對應中每個檢視的專案。 第二種方法會計算單一容器對應的雜湊值,並在執行時間用來驗證模型自預先產生檢視後尚未變更。 針對涉及多個容器對應的複雜案例,會提供這兩種方法的覆寫。

產生檢視時,您將呼叫 GenerateViews 方法,然後寫出產生的 EntitySetBase 和 DbMappingView。 您也需要儲存 ComputeMappingHashValue 方法所產生的雜湊。

載入檢視

若要載入 GenerateViews 方法所產生的檢視,您可以為 EF 提供繼承自 DbMappingViewCache 抽象類別的類別。 DbMappingViewCache 指定兩種方法,您必須實作:

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

MappingHashValue 屬性必須傳回 ComputeMappingHashValue 方法所產生的雜湊。 當 EF 要求檢視時,它會先產生模型雜湊值,並將其與這個屬性所傳回的雜湊進行比較。 如果它們不相符,EF 會擲回 EntityCommandCompilationException 例外狀況。

GetView 方法會接受 EntitySetBase,而您需要傳回 DbMappingVIew,其中包含針對該物件所產生的 EntitySql,與 GenerateViews 方法所產生字典中給定 EntitySetBase 相關聯的 DbMappingVIew。 如果 EF 要求您沒有的檢視,GetView 應該會傳回 null。

以下是使用上述 Power Tools 產生的 DbMappingViewCache 擷取,其中我們看到儲存和擷取 EntitySql 所需的其中一種方式。

    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,並指定其建立的內容。 在下列程式碼中,我們會將 BlogCoNtext 與 MyMappingViewCache 類別產生關聯。

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

針對更複雜的案例,您可以藉由指定對應檢視快取處理站來提供對應檢視快取實例。 這可以藉由實作抽象類別 System.Data.Entity.Infrastructure.MappingViews.DbMappingViewCacheFactory 來完成。 您可以使用 儲存體MappingItemCollection.MappingViewCacheFactoryproperty 來擷取或設定所使用的對應檢視快取處理站實例。