problemas de rendimiento marco de la entidad añadiendo niño a la lista

votos
1

Estoy trabajando en un proyecto en el que estamos utilizando Entity Framework 6.1.3. En este momento estamos experimentando problemas de rendimiento bastante grande cuando se añade un objeto secundario a una lista de la entidad matriz (véase el ejemplo de código siguiente).

Estamos utilizando perezoso de carga, por lo que lo que he notado es que todo funciona bien hasta que llamamos _parent.Children.Add(child);ya que parece que cargar todos los niños a partir de la base de datos sólo para ser capaz de añadir una nueva. Dado que algunos de nuestros objetos padres tienen unos 50.000 niños, esto está retrasando esta simple llamada de inserción por 7-8 segundos y, a veces incluso causando tiempos de espera.

Para mí no tiene mucho sentido para Entity Framework para cargar todos los niños simplemente con el fin de añadir una, por lo que hay una manera que puede evitar esto o se trata de un diseño de defecto de Entity Framework y debería Podemos encontrar una solución?

Obviamente gustaría encontrar una solución para esto y preferiría no tener que implementar consultas ADO puros para éste problema.

¡Gracias!

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);
    }
}
Publicado el 19/12/2018 a las 14:16
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
2

Para mí no tiene mucho sentido para Entity Framework para cargar todos los niños simplemente con el fin de añadir una

La carga diferida se produce la primera vez que accede a una propiedad de navegación a través de su comprador . Y el código de ejemplo

_parent.Children.Add(child);

consta de dos operaciones:

(1) recuperar la Childrenpropiedad (a través de la propiedad getter !):

var children = _parent.Children;

(2) realizar alguna operación sobre el mismo (llamado Addmétodo en este caso):

children.Add(child);

La carga lenta se produce debido a la operación (1). Como se puede ver, EF tiene nada que ver con eso porque no tiene control sobre él. Y no hay manera de saber lo que vas a hacer con ese valor de propiedad - enumerar ella, hacer un conteo o uso Add, Removeetc. métodos.

Aquí están algunas soluciones.

En primer lugar, ¿por qué el uso de la carga diferida en absoluto? Tiene efectos secundarios y las ineficiencias tantos, y todo lo que puede ser resuelto fácilmente por EF proporcionado fuera de la caja de carga ansioso a través de Includemétodos. Es por eso por defecto EF Core ( "el futuro de la EF") no utiliza la carga diferida por defecto y requiere un paquete y procedimiento especial para habilitarlo.

En segundo lugar, si usted insiste utilizando la carga diferida, entonces usted tiene las siguientes dos opciones:

(A) Desactivar carga lenta durante las modificaciones de datos (requiere acceso a / control de la DbContextinstancia):

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

Esto también requiere la propiedad de colección que ser inicializado con el fin de evitar NRE.

(B) el uso de campo respaldo explícito y proporcionar algún acceso directo a la misma (para evitar la activación de la carga de descanso junto a propiedad de acceso). Por ejemplo:

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); 
    }
}
Respondida el 19/12/2018 a las 15:20
fuente por usuario

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