在多個具有相同 DbCoNtext 類型的模型之間交替

OnModelCreating 建的模型可以使用內容上的 屬性來變更模型建置方式。 例如,假設您想要根據某些屬性以不同的方式設定實體:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    if (UseIntProperty)
    {
        modelBuilder.Entity<ConfigurableEntity>().Ignore(e => e.StringProperty);
    }
    else
    {
        modelBuilder.Entity<ConfigurableEntity>().Ignore(e => e.IntProperty);
    }
}

不幸的是,此程式碼無法依預期運作,因為 EF 只會建置模型並 OnModelCreating 執行一次,因此會基於效能原因快取結果。 不過,您可以連結至模型快取機制,讓 EF 知道產生不同模型的屬性。

IModelCacheKeyFactory

EF 會使用 IModelCacheKeyFactory 來產生模型的快取索引鍵;根據預設,EF 會假設針對任何指定的內容類型,模型會相同,因此此服務的預設實作會傳回只包含內容類型的索引鍵。 若要從相同的內容類型產生不同的模型,您需要使用正確的實作來取代 IModelCacheKeyFactory 服務;產生的索引鍵將會使用 Equals 方法與其他模型索引鍵進行比較,並考慮影響模型的所有變數。

下列實 UseIntProperty 作會在產生模型快取索引鍵時納入考慮:

public class DynamicModelCacheKeyFactory : IModelCacheKeyFactory
{
    public object Create(DbContext context, bool designTime)
        => context is DynamicContext dynamicContext
            ? (context.GetType(), dynamicContext.UseIntProperty, designTime)
            : (object)context.GetType();
}

您也必須實作 Create 方法的多載,該方法也會處理設計階段模型快取。 如下列範例所示:

public class DynamicModelCacheKeyFactoryDesignTimeSupport : IModelCacheKeyFactory
{
    public object Create(DbContext context, bool designTime)
        => context is DynamicContext dynamicContext
            ? (context.GetType(), dynamicContext.UseIntProperty, designTime)
            : (object)context.GetType();

    public object Create(DbContext context)
        => Create(context, false);
}

最後,在內容的內容 OnConfiguring 中註冊您的新 IModelCacheKeyFactory 專案:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseInMemoryDatabase("DynamicContext")
        .ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>();

如需更多內容, 請參閱完整的範例專案