wake-up-neo.net

Das Entity-Framework wird nach jeder Kompilierung zum ersten Mal sehr langsam geladen

Wie der Titel vermuten lässt, habe ich ein Problem mit der ersten Abfrage einer SQL Server-Datenbank unter Verwendung von Entity Framework. Ich habe versucht, nach einer Antwort zu suchen, aber niemand scheint tatsächlich eine Lösung dafür zu haben.

Die Tests wurden in Visual Studio 2012 mit Entity Framework 6 durchgeführt. Ich habe auch die T4-Ansichtenvorlage verwendet, um die Ansichten vorzukompilieren. Die Datenbank wurde auf einem SQL Server 2008 erstellt. Wir haben ungefähr 400 POCOs (400 Zuordnungsdateien), nur 100 Zeilen Daten in der Datenbanktabelle.

Nach dem Capture ist mein Testcode und Ergebnis.

static void Main(string[] args){
    Stopwatch st=new Stopwatch();
    st.Start();
    new TestDbContext().Set<Table1>.FirstOrDefault();
    st.stop();
    Console.WriteLine("First Time "+st.ElapsedMilliseconds+ " milliseconds");

    st.Reset();
    st.Start();
    new TestDbContext().Set<Table1>.FirstOrDefault();
    st.stop();
    Console.WriteLine("Second Time "+st.ElapsedMilliseconds+ " milliseconds");
}

Testergebnisse

First Time 15480 milliseconds
Second Time 10 milliseconds
39
LeoLi

Bei der ersten Abfrage kompiliert EF das Modell. Für ein so großes Modell kann dies einige Zeit in Anspruch nehmen. 

Hier sind 3 Vorschläge: http://www.fusonic.net/de/blog/2014/07/09/drei-steps-for-fast-entityframework-6.1-first-query-performance/

Eine Zusammenfassung:

  1. Verwenden eines zwischengespeicherten Datenbankspeicher
  2. Erstellen Sie vorkompilierte Ansichten
  3. Erstellen Sie mit n-gen eine vorkompilierte Version des Entityframeworks, um Jitting zu vermeiden 

Ich würde auch sicherstellen, dass ich die Anwendung im Release-Modus kompiliere, wenn ich die Benchmarks durchführe.

Eine andere Lösung ist das Aufteilen von DBContext. 400 Entitäten sind eine Menge und es sollte schöner sein, mit kleineren Brocken zu arbeiten. Ich habe es nicht ausprobiert, aber ich gehe davon aus, dass es möglich wäre, die Modelle einzeln zu bauen, was bedeutet, dass keine einzelne Last 15 Sekunden benötigt. Sehen Sie diesen Beitrag von Julie Lerman https://msdn.Microsoft.com/en-us/magazine/jj883952.aspx

34
Mikael Eliasson

Mit EF Core können Sie das Modell frühzeitig cheaten und laden, nachdem Sie services.AddDbContext aufgerufen haben (Sie können wahrscheinlich auch mit EF6 etwas ähnliches tun, aber ich habe es nicht getestet).

services.AddDbContext<MyDbContext>(options => ...);
var options = services.BuildServiceProvider()
                      .GetRequiredService<DbContextOptions<MyDbContext>>();
Task.Run(() =>
{
    using(var dbContext = new MyDbContext(options))
    {
        var model = dbContext.Model; //force the model creation
    }
});

Dadurch wird das Modell des dbcontext in einem anderen Thread erstellt, während der Rest der Initialisierung der Anwendung (und möglicherweise anderer Aufwärmvorgänge) und des Beginns einer Anforderung ausgeführt wird. Auf diese Weise wird es früher fertig sein. Wenn Sie es benötigen, wartet EFCore auf die Erstellung des Modells, wenn es noch nicht fertig ist. Die Variable Model wird von allen DbContext-Instanzen gemeinsam genutzt. Es ist also in Ordnung, diesen Dummy-Dbcontext abzufeuern und zu vergessen.

1
Yepeekai

Sie können so etwas versuchen: (es hat für mich funktioniert)

protected void Application_Start()
{

    Start(() =>
    {
        using (EF.DMEntities context = new EF.DMEntities())
        {
            context.DMUsers.FirstOrDefault();
        }
    });
}
private void Start(Action a)
{
    a.BeginInvoke(null, null);
} 

Entity Framework - Erste Abfrage langsam

1
AllmanTool

Wenn Sie viele Tabellen haben, die nicht in c # verwendet werden, schließen Sie diese aus. 

Fügen Sie eine Teilklasse hinzu, fügen Sie den folgenden Code hinzu und referenzieren Sie diese Funktion in OnModelCreating 

void ExcludedTables(DbModelBuilder modelBuilder)
{
    modelBuilder.Ignore<Table1>();
    modelBuilder.Ignore<Table>();
   // And so on
}
0
roncansan

diese Arbeit für mich:

using (MyEntities db = new MyEntities())                
{
   db.Configuration.AutoDetectChangesEnabled = false; // <----- trick
   db.Configuration.LazyLoadingEnabled = false; // <----- trick

   DateTime Created = DateTime.Now;

   var obj = from tbl in db.MyTable
      where DateTime.Compare(tbl.Created, Created) == 0
      select tbl;

   dataGrid1.ItemsSource = obj.ToList();
   dataGrid.Items.Refresh();
}
0
user3047352