Entity Framework problèmes de performance en ajoutant l'enfant à la liste

voix
1

Je travaille sur un projet où nous utilisons Entity Framework 6.1.3. En ce moment, nous vivons assez gros problèmes de performance lors de l'ajout d'un objet enfant à une liste de l'entité mère (voir exemple de code ci-dessous).

Nous utilisons de chargement paresseux, donc ce que je remarqué est que tout fonctionne bien jusqu'à ce que nous appelons , _parent.Children.Add(child);car il semble charger tous les enfants de la base de données juste pour être en mesure d'ajouter un nouveau. Étant donné que certains de nos objets parents ont environ 50 000 enfants, ce qui retarde ce simple appel d'insertion par 7-8 secondes et parfois même causant les délais d' attente.

Pour moi, il ne fait pas vraiment de sens pour Entity Framework pour charger tous les enfants juste pour ajouter un, donc est-il un moyen que je peux éviter ceci ou est-ce une conception faille et devrions-nous trouver une solution de contournement Entity Framework?

J'aime évidemment trouver une solution pour cela et préfère ne pas avoir à implémenter des requêtes ADO pures pour ce seul problème.

Merci!

public class Parent 
{
    public Guid Id { get; set; }
    public virtual ICollection<Child> Children { get; set; }
}

public class Child
{
    public Guid Id { get; set; }
}

public class ParentAggregate
{
    private readonly Parent _state;

    public ParentAggregate(Parent state)
    {
        _state = state;
    }

    public void AddChild(Guid id)
    {
        var child = new Child { Id = id };
        _state.Children.Add(child);
    }
}
Créé 19/12/2018 à 14:16
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
2

Pour moi, il ne fait pas vraiment de sens pour Entity Framework pour charger tous les enfants juste pour ajouter une

Le chargement paresseux se produit la première fois que vous accédez à une propriété de navigation par son getter . Et l'exemple de code

_parent.Children.Add(child);

consiste en deux opérations:

(1) récupérer la Childrenpropriété (par la propriété getter !):

var children = _parent.Children;

(2) effectuer une opération sur elle (appel Addméthode dans ce cas):

children.Add(child);

Le chargement différé se produit en raison de l'opération (1). Comme vous pouvez le voir, EF n'a rien à voir avec ce parce qu'il n'a pas le contrôle. Et il n'y a aucun moyen de savoir ce que vous allez faire avec cette valeur de la propriété - énumérer, prenez un compte ou de l' utilisation Add, les Removeméthodes , etc..

Voici quelques solutions.

Tout d' abord, pourquoi l' utilisation de chargement paresseux du tout? Il a tant d'effets secondaires et de l' inefficacité, et tout ce qu'ils peuvent être facilement résolu par EF fourni hors de la boîte de chargement désireux par des Includeméthodes. Voilà pourquoi par défaut EF de base ( « l'avenir de EF ») ne pas utiliser le chargement paresseux par défaut et nécessite un package spécial et la procédure pour l' activer.

En second lieu, si vous insistez en utilisant le chargement paresseux, alors vous avez les deux options suivantes:

(A) Désactiver le chargement différé pendant les modifications de données (nécessite un accès à / commande de l' DbContextinstance):

dbContext.Configuration.LazyLoadingEnabled = false;
_parent.Children.Add(child);
dbContext.Configuration.LazyLoadingEnabled = true;

Cela nécessite également la propriété de collection à initialiser afin d'éviter NRE.

(B) utiliser le champ de support explicite et fournir un accès direct à ce (pour éviter le déclenchement de la charge paresseux par accesseur de propriété). Par exemple:

public class Parent 
{
    public Guid Id { get; set; }

    private ICollection<Child> children;
    public virtual ICollection<Child> Children { get => children; set => children = value; }

    public void Add(Child child)
    {
        // use the backing field directly
        if (children == null) children = new HashSet<Child>();
        children.Add(child); 
    }
}
Créé 19/12/2018 à 15:20
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more