2016-08-07 32 views
0

Ich entwickle ein Projekt EF mit 6. Also habe ich diese Schichten in meinem Projekt haben:Entity Framework ist sehr, sehr langsam in meinem Projekt ca. 2 min für große Datenmengen

  1. Database (DbContext)
  2. IRepo
  3. Repo
  4. UI

konfiguriert ich meine EF in Datenbankschicht, wie Sie hier sehen können:

public class DataContext : DbContext 
{ 
    public DataContext() : base("DefaultConnection") 
    { 
      this.Configuration.LazyLoadingEnabled = false; 
      this.Configuration.ProxyCreationEnabled = false; 

      Database.SetInitializer(
       new MigrateDatabaseToLatestVersion<DataContext, MigrationsConfiguration>() 
       ); 
    } 

    public DbSet<Line> Lines { get; set; } 
    public DbSet<Spool> Spools { get; set; } 
    /...... 
} 

In meinem IRepo definiere ich meine Schnittstellen:

public interface IEndRepository 
{ 
     IQueryable<End> Get(); 
     bool Save(); 
     bool Add(End newValue); 
     bool Delete(End deletedValue); 
     bool Edit(End UpdatedValue); 
     IQueryable<End> FindById(int Id); 
} 

Und ich implementieren diese Schnittstellen, und in meiner Anwendung (Windows-Formular) Ich injizieren diese Repositorys zu meiner Form in Repo mit ninject. Einer meiner Abfrage wie folgt aussieht:

public IQueryable<ViewMaterial> ViewIMaterial() 
{ 
    return (from i in _ctx.Materials 
      join material in _ctx.MaterialDescriptions on i.MaterialDescriptionId equals material.Id 
      join Line in _ctx.Lines on i.LineId equals Line.Id 
      join user in _ctx.Users on i.UserId equals user.Id 
      join sheet in _ctx.Sheets on i.SheetId equals sheet.Id 
      select new ViewMaterial 
        { 
         Id = i.Id, 
         LineId = Line.LineNumber, 
         SheetId = sheet.SheetNumber, 
         Discipline = i.Discipline, 
         Quantity = i.Quantity, 
         MaterialDescriptionId = material.ItemCode, 
         SubmitDateTime = i.SubmitDateTime, 
         UserId = user.FullName 
        }); 
} 

Diese Abfrage ist innerhalb Repo-Schicht, die Anzahl der Zeilen in Material ist 16000, materiaddescription ist 42000, Linie 1300 und Blatt ist 3300, Benutzer 1.

Wenn ich diese Abfrage ausführen, wird das Ergebnis nach 3 Minuten generiert, und wenn es geladen wird, arbeitet meine Anwendung sehr langsam.

Ich ändere die erste Zeile meiner Abfrage auf from i in _ctx.Materials.take(20), aber das gleiche Problem.

+0

tun Sie Schleife über diese Einträge in einer foreach-Schleife? Rufen Sie vorher .ToList() auf. Wenn Sie keine Änderungen an den Einträgen vornehmen müssen, verwenden Sie .AsNoTracking(). – DevilSuichiro

+0

@DevilSuichiro Ich habe keine Schleife beim Abrufen von Daten, wo soll ich .tolist aufrufen? –

+0

entweder direkt in dieser Funktion, oder wo auch immer Sie die Abfrage ausführen, die von diesem IQueryable erstellt wird. – DevilSuichiro

Antwort

0

Ich denke der Grund, warum es sehr langsam ist, ist die multiple "Join". Mehr als 2 "Join" in einer einzigen Anfrage mit EF könnte schnell schwer sein.

Versuchen Sie, die Anfrage zu trennen oder ändern Sie Ihren Code zu Lazy Laden Sie alle Daten, die Sie benötigen, direkt nach der Abfrage mit .Load() zum Beispiel. folgenden Code

0

Versuchen:

public IQueryable<ViewMaterial> ViewIMaterial() 
{ 
    return _ctx.Materials.Take(20) 
     .Select(e=> new ViewMaterial 
     { 
      Id = e.Id, 
      LineId = e.Line.LineNumber, 
      SheetId = e.Sheet.SheetNumber, 
      Discipline = e.Discipline, 
      Quantity = e.Quantity, 
      MaterialDescriptionId = e.MaterialDescriptions.ItemCode, 
      SubmitDateTime = e.SubmitDateTime, 
      UserId = e.User.FullName 
     }); 
}