12

I have found that a large component of EF's slow startup time can be related to getting provider information from the database. This is very annoying when running integration tests or doing other iterative development. Can anyone explain why getting provider information is slow or what may be done about it? We are using EF5.

Here's an example that demonstrates this behavior:

void Main()
{
    Database.SetInitializer<ModelDbContext>(null);
    Database.SetInitializer<ModelCreatingDbContext>(null);

    // passing the provider information in is very fast
    var sw2 = Stopwatch.StartNew();
    var builder = new DbModelBuilder();
    builder.Entity<SqlConnectionStringBuilder>().HasKey(c => c.ConnectionString).ToTable("strings");
    var q2 = new ModelDbContext(builder.Build(new DbProviderInfo("System.Data.SqlClient", "2008")).Compile()).Set<SqlConnectionStringBuilder>().Take(1).ToString();
    Console.WriteLine(sw2.Elapsed); // < 1 second

    // letting EF determine it from the connection string is sometimes very slow
    var sw1 = Stopwatch.StartNew();
    var q = new ModelCreatingDbContext().Set<SqlConnectionStringBuilder>().Take(1).ToString();
    Console.WriteLine(sw1.Elapsed); // can be upwards of 13 seconds!

}

public class ModelDbContext : DbContext {
    public static readonly string Connection = // connection string here

    public ModelDbContext(DbCompiledModel model) 
        : base(Connection, model) { }
}

public class ModelCreatingDbContext : DbContext {
    public ModelCreatingDbContext() : base(ModelDbContext.Connection) { }

    protected override void OnModelCreating(DbModelBuilder builder) {
        builder.Entity<SqlConnectionStringBuilder>().HasKey(c => c.ConnectionString).ToTable("strings");

        base.OnModelCreating(builder);
    }
}
ChaseMedallion
  • 19,262
  • 13
  • 76
  • 137
  • The slow performance may be related to Mapping Views. You need to pre-generated the mapping views. See link http://msdn.microsoft.com/en-us/data/dn469601 – Priyank Dec 27 '13 at 11:02
  • @Priyank: I'm aware that view generation is another performance issue with EF, but I don't see how it applies here. Both contexts will need to generate views; the only difference is getting provider information. – ChaseMedallion Dec 27 '13 at 23:01
  • Would it help if you provided the provider information in a custom connection factory ? – Bill Greer Jan 29 '14 at 00:40
  • @BillGreer is this meaningfully different than passing a DbProviderInfo as I do below? – ChaseMedallion Jan 29 '14 at 23:51
  • Sorry. I'm unsure. :) – Bill Greer Jan 30 '14 at 15:31
  • Did a local test with EF 5.0 and 6.0.2, couldn't find the problems you are referring to. Have you found the exact position of the bottleneck? VS and Performance Analysis might help. – Frode Nilsen Feb 03 '14 at 13:14
  • @FrodeNilsen: I've profiled using dotTrace, and found that the slow part is getting the provider manifest token. Unfortunately, this isn't 100% reproducible. It could even be related to how we structure our connection strings. If I understood better what EF was actually doing to retrieve the token, that might help diagnose. – ChaseMedallion Feb 09 '14 at 13:52
  • I also can't reproduce it. I get even faster results in the second stop watch (132 ms) than in the first (381 ms). Tested with EF 5.0/.NET 4.5/SQL Server Express 2012 and as connection string: `@"Server=.\SQLEXPRESS; Database=MyDb; Integrated Security=True;"` – Slauma Mar 02 '14 at 14:52
  • BTW: You should add the info that the problem isn't 100% reproducible to the question along with an explanation what that means exactly. Do you run the program 10 times and it happens once or 9 times? Does it only happen after you restart the PC? Does the problem disappear if you change the connection string? And how do you change it? Etc., etc.... – Slauma Mar 02 '14 at 15:04

0 Answers0