Instanciation d'un contexte dans LINQ aux entités

entity entity-framework linq linq-to-entities

Question

J'ai vu deux manières différentes que les programmeurs abordent lors de la création d'un contexte d'entité dans leur code.

Le premier est comme tel, et vous pouvez le trouver partout dans les exemples de code MSDN:

public void DoSomething() {
     using (TaxableEducationEntities context = new TaxableEducationEntities()) {
          // business logic and whatever else
     }
}

La seconde consiste à créer le contexte en tant qu'attribut privé dans une classe qui encapsule votre logique métier. Donc, vous auriez quelque chose comme:

public class Education_LINQ {

        private TaxableEducationEntities context = new TaxableEducationEntities();

        public void DoSomething() {
            var result = from a in context.luAction
                         select a;

            // business logic and whatever else
        }
}

De quelle manière est plus efficace?

Supposons que vous avez deux méthodes, l'une appelée DoSomething1 () et une autre appelée DoSomething2 (), et que les deux méthodes incorporent l'instruction using pour ouvrir le contexte et tout faire avec. Si vous appeliez une méthode après l'autre, y aurait-il une surcharge superflue, étant donné que les deux méthodes créent essentiellement le contexte et le nettoient ensuite? Plutôt que d'avoir un seul attribut privé créé lorsqu'un objet de classe est instancié, puis nettoyé à son tour lorsque l'objet sort de la portée?

Réponse acceptée

La création d'un nouveau ObjectContext implique à chaque fois "quelques" frais généraux. La surcharge impliquée consiste essentiellement à copier les métadonnées d'un cache global dans des métadonnées associées au ObjectContext spécifique.

Ces frais généraux sont relativement mineurs, il est donc souvent inutile de s’inquiéter, en particulier si l’on tient compte de la sécurité supplémentaire inhérente au mode d’utilisation.

Pour moi, l'option que vous choisissez dépend de choses comme:

  1. Quelle est la durée de vie de votre classe d'emballage? S'il dure longtemps, ObjectContext risque de contenir beaucoup d'entités en ralentissement au fil du temps. Donc, un nouveau ObjectContext à chaque fois peut être une bonne idée.
  2. Les appels aux méthodes de votre classe de wrapping sont-ils synchronisés? La classe ObjectContext elle-même n'est pas threadsafe, donc si vous utilisez le second modèle, vous devez vous assurer que votre classe / référentiel d'habillage est thread-safe si vous souhaitez que plusieurs threads l'appellent.
  3. Les méthodes sont-elles essentiellement indépendantes? Dans ce cas, vous pourriez avoir des effets secondaires inattendus s’ils partagent un même contexte entre les méthodes.

En général, je recommande que, si les méthodes sont sans état, c'est-à-dire qu'il faut tirer et oublier un nouveau contexte pour chaque méthode est probablement une bonne idée.

Toutefois, si vous avez une forme d’état relativement courte à vie ou quelque chose comme ça, alors un contexte partagé est peut-être une meilleure idée.

MISE À JOUR: j'ai pris le temps de préparer une réponse plus complète


Réponse populaire

La deuxième option ne nettoie pas en soi si c'est ce que vous voulez dire. Je préfère utiliser la version d'ObjectContext à chaque fois, car je n'ai pas à la disposer par la suite. Je ne suis pas sûr d'avoir bien compris la question ... Trop d'heures passées à programmer aujourd'hui.

public class UserManagerRepository : IUserManagerRepository, IDisposable
{
    private readonly Entities _context = new Entities();
    private bool _disposed;

    public User Create(User user, int countryId)
    {
        user.Country = GetCountry(countryId);
        _context.AddToUser(user);
        _context.SaveChanges();
        return user;
    }
}

Ensuite, pour utiliser ce référentiel, je fais quelque chose comme:

using(var repository = new UserManagerRepository())
{
    repository.Create(user);
}


Related

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