2017-10-15 24 views
0

Je cette méthode qui permet d'économiser une entité avec ses éléments connexes (many-to-many),L'ajout ou la mise à jour d'une entité dans une boucle foreach prend trop de temps avant d'appeler SaveChanges()?

private static void Save<T>(TbCommonHistoryLog log, List<T> lstDetails) where T : IHasSerial 
{ 
    foreach (var item in lstDetails.OrderBy(x => x.Serial)) 
    { 
     var ser = SerializeObject(item); 
     var record = oContext.TbHistoryLog_Lists.FirstOrDefault(x => x.ListObjectJson == ser); 
     if (record == null) //add new list item 
     { 
      TbCommonHistoryLog_Lists listObject = new TbCommonHistoryLog_Lists() 
      { 
       ListObjectJson = SerializeObject(item) 
      }; 
      var details = new TbCommonHistoryLogDetails { TbHistoryLog = log, TbHistoryLog_Lists = listObject }; 
      oContext.TbHistoryLogDetails.Add(details); 
     } 
     else //attach an existing list item 
     { 
      var o = oContext.TbHistoryLog_Lists.Find(record.Id); 
      oContext.TbHistoryLog_Lists.Attach(o); 
      var details = new TbCommonHistoryLogDetails { TbHistoryLog = log, TbHistoryLog_Lists = o }; 
      oContext.TbHistoryLogDetails.Add(details); 
     } 
    } 
    oContext.BulkSaveChanges(); 
} 

J'ai deux tables: TbCommonHistoryLog, TbCommonHistoryLog_Lists, qui sont nombreux à plusieurs, la table se joindre à Ce que je fais ici est un audit pour les modèles maître-détail, tous les audits sont sérialisés à JSON en DB, j'enregistre l'objet principal dans la table TbCommonHistoryLog, et chaque élément de la liste dans la table TbHistoryLog_Lists, dans le mthod ci-dessus, je vérifie si l'élément de liste existe déjà dans la base de données ou non pour éviter la duplication. mais ce processus prend plus de 15 secondes, ce qui est très long, je ne peux pas comprendre ce que je fais mal ici .. s'il vous plaît aider?

Répondre

1

Pour chaque article de la collection, vous interrogez la base de données. Ma suggestion est de sauvegarder les enregistrements dans var, puis de demander à la variable si l'item est dans la base de données.

var databaseRecords = oContext.TbHistoryLog_Lists.ToList(); 

Puis dans la boucle:

var record = databaseRecords.FirstOrDefault(x => x.ListObjectJson == ser);