2016-08-07 1 views
0

Je développe un projet en utilisant EF 6. J'ai donc ces couches dans mon projet:Entity Framework est très lent dans mon projet d'environ 2 minutes pour énorme quantité de données

  1. Database (dbcontext)
  2. IRepo
  3. repo
  4. UI

Je configuré mon EF dans la couche de base de données que vous pouvez voir ici:

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; } 
    /...... 
} 

Dans mon IRepo je définis mes interfaces:

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); 
} 

Et repo ces interfaces je mets en œuvre, et dans ma demande (formulaire Windows) J'injectent ces dépôts à mon formulaire en utilisant ninject. Une de ma requête ressemble à ceci:

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 
        }); 
} 

Cette requête est couche intérieure Repo, le nombre de lignes en matériau est 16000, materiaddescription est 42000, la ligne est 1300 et la feuille est 3300, l'utilisateur est 1.

Lorsque j'exécute cette requête, le résultat est généré après 3 minutes, et quand il est chargé, mon application fonctionne très lentement.

Je modifie la première ligne de ma requête à from i in _ctx.Materials.take(20) mais le même problème.

+0

boucle pensez-vous sur ces entrées dans une boucle de foreach? appelez .ToList() avant alors. En outre, si vous n'avez pas besoin de modifier les entrées, utilisez .AsNoTracking(). – DevilSuichiro

+0

@DevilSuichiro je n'ai pas de boucle dans l'extraction de données, où devrais-je appeler .tolist? –

+0

soit directement dans cette fonction, soit là où vous exécutez réellement la requête créée par ce IQueryable. – DevilSuichiro

Répondre

0

Je pense que la raison pour laquelle c'est très lent est la "jointure" multiple. Faire plus de 2 "join" dans une seule requête en utilisant EF pourrait être lourd. Essayez de séparer la demande ou de changer votre code en Lazy Charger toutes les données dont vous avez besoin juste après la requête en utilisant. Load() par exemple.

0

Essayez le code suivant:

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 
     }); 
}