Entity Framework enregistre de manière sélective les entités suivies du contexte et en insère d'autres

bulkinsert c# entity-framework sqlbulkcopy

Question

Je suis assez nouveau pour Entity Framework. J'ai rencontré un scénario où j'ai mes entités:

public class Company{
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<Project> Projects{ get; set; }
}

public class Project
{
    public int Id { get; set; }
    public List<ProjectRecord> ProjectRecords { get; set; }
    public DateTime ProjectDate { get; set; }
}

public class ProjectRecord
{
    public int Id { get; set; }
    public virtual Project Project{ get; set; }
    public string Status { get; set; }
}

Je crée mon contexte, charge l'employeur, puis passe l'objet employeur à une autre classe qui ajoute un projet à mon entité employeur, puis je charge environ 300 000 enregistrements de projet à partir d'un fichier et ajoute cette liste d'enregistrements au projet.

Entity Framework suit tout cela, et bien que ce ne soit pas particulièrement rapide, ce n'est pas si mal.

La partie lente est quand j'appelle SaveChanges () sur le contexte. Je souhaitais pouvoir détacher la liste des enregistrements de projet de mon contexte et enregistrer le projet sans eux, puis utiliser l'extension d'insertion en bloc fournie à partir de https://efbulkinsert.codeplex.com/ pour insérer en bloc les ProjectRecords séparément. Cependant, je ne pouvais pas trouver un moyen de détacher ProjectRecords.

J'ai donc essayé d'insérer en bloc l'entité entière du projet:

        context.BulkInsert(context,
            context.ChangeTracker.Entries()
                .Where(x => x.State == EntityState.Added)
                .Select(x => x.Entity)
                .OfType<Project>()
                .ToList());

        context.SaveChanges();

Cependant, cela semble prendre beaucoup de temps pour ne rien faire à la base de données. Je pense donc que je m'y prends complètement mal.

Je n'ai pas le contexte disponible lorsque j'ajoute le projet à l'entité employeur et je ne veux pas le rendre disponible si je peux l'éviter, car j'essaie de les séparer.

Existe-t-il un moyen d'améliorer les performances, utilisez l'extension d'insertion en bloc ou la copie en bloc SQL à partir de l'endroit où j'appelle SaveChanges dans mon contexte?

Toute aide est grandement appréciée.

Réponse acceptée

Une suggestion serait de ne pas attacher les ProjectRecords au contexte en premier lieu lors du chargement, si cela est possible. Vous pourriez utiliser quelque chose comme un

Dictionary<Project, List<ProjectRecord>>

pour les conserver et pour vous aider à récupérer le Project et à définir ProjectRecord.Project lorsque vous enregistrez.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow