Search code examples
entity-frameworkef-code-firstef-power-tools

Entity Framework Code First Pre-Compiled Views Not Speeding Up First Call


I used EF PowerTools (EF5) in VS2012 to generate pre-compiled views for my large code-first DataContext. Unfortunately, this didn't help speed up the first call to the data context. It still takes about 13 seconds. Are there some considerations for using pre-compiled views that I'm not taking into account? I am not using migrations and I'm disabling database initialization.

<connectionStrings>
    <add name="MyDataContext" connectionString="..." providerName="System.Data.SqlClient" />
</connectionStrings>

<entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <contexts>
        <context type="MyNameSpace.MyDataContext, MyNameSpaceAssembly" disableDatabaseInitialization="true" />
    </contexts>
</entityFramework>

Solution

  • After digging through the Internet with various search terms, I was able to figure this out. There is a problem using precompiled views if your entities are not in the same assembly as the data context. The issue is described here:

    Which assembly should I place the compiled views for entity framework code first when context is in a separate project from the domain classes

    There is a workaround, however, I find it to be quite a hack. The first DbSet entity defined in the context must reside in the same assembly as the DataContext. I created this arbitrary entity class in my context's assembly:

    public class PreCompiledView
    {
        public int PreCompiledViewId { get; set; }
    }
    

    and added the DbSet to my context:

    public class MyDataContext : DbContext
    {
        #region DBSets
    
        // HACK: Enable pre-compiled views
        internal DbSet<PreCompiledView> PreCompiledViews { get; set; }
    
        // My entity sets
        public DbSet<MyOtherAssemblyEntity> MyOtherAssemblyEntities { get; set; }
        ...
    
        #endregion
    }
    

    My pre-compiled views are now reflected and used by the datacontext. In my custom database initializer Seed() override, I execute a SQL DROP statement to drop the dbo.PrecompiledViews table in order to keep it hidden from developers.

    context.Database.ExecuteSqlCommand("DROP TABLE [dbo].[PreCompiledViews]");