Entity Framework problemy z wydajnością dodanie dziecka do listy

głosy
1

Pracuję nad projektem, gdzie jesteśmy przy użyciu Entity Framework 6.1.3. Teraz jesteśmy świadkami dość duże problemy z wydajnością podczas dodawania obiektu podrzędnego na liście jednostki dominującej (patrz przykładowy kod poniżej).

Używamy leniwe ładowanie, więc co zauważyłem jest to, że wszystko działa dobrze, dopóki my nazywamy _parent.Children.Add(child);ponieważ wydaje się załadować wszystkie dzieci z bazy danych tylko, aby móc dodać nowe. Ponieważ niektóre z naszych obiektów nadrzędnych mają około 50.000 dzieci, to opóźnia to proste połączenie wkładki przez 7-8 sekund, a czasami nawet powodując opóźnień.

Dla mnie to nie ma sensu dla Entity Framework, aby załadować wszystkie dzieci po prostu, aby dodać jeden, więc jest jakiś sposób mogę tego uniknąć lub czy jest to projekt-wada Entity Framework i powinniśmy znaleźć obejście?

Chciałbym oczywiście podoba się znaleźć rozwiązanie tego problemu i woleliby nie posiadające do wdrożenia czystych zapytań ADO dla tego jednego problemu.

Dzięki!

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);
    }
}
Utwórz 19/12/2018 o 14:16
źródło użytkownik
W innych językach...                            


1 odpowiedzi

głosy
2

Dla mnie to nie ma sensu dla Entity Framework, aby załadować wszystkie dzieci po prostu, aby dodać jedną

Leniwy ładowanie odbywa się podczas pierwszego dostępu właściwość nawigację poprzez getter . I przykładowy kod

_parent.Children.Add(child);

Składa się z dwóch operacji:

(1) odzyskać Childrenwłasność (za pośrednictwem właściwości getter !):

var children = _parent.Children;

(2) wykonywania pewnych operacji na nim (połączenia Addmetodą w tym przypadku):

children.Add(child);

Lazy ładowanie odbywa się z powodu pracy (1). Jak widać, EF nie ma nic wspólnego z tym, ponieważ nie ma nad nim kontroli. I nie ma sposobu, aby wiedzieć, co masz zamiar zrobić z tym wartości nieruchomości - wyliczyć ją wziąć licznik lub wykorzystanie Add, Removeitp metod.

Oto niektóre rozwiązania.

Po pierwsze, dlaczego używając leniwy załadunku w ogóle? Ma tak wiele skutków ubocznych i nieefektywność, a wszystkie one mogą być łatwo rozwiązany przez EF dostarczonych z pudełka zachłanne ładowanie za pośrednictwem Includemetod. Dlatego domyślnie EF rdzeniowy ( „przyszłość EF”) nie używa leniwy załadunku domyślnie i wymaga specjalnego pakietu i procedury umożliwiające jej.

Po drugie, jeśli nalegać używając leniwy załadunku, to masz dwie następujące opcje:

(A) Wyłącz lazy ładunkowych podczas modyfikacji danych (wymaga dostępu do sterowania / na DbContextprzykład):

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

Wymaga to także właściwość gromadzenia zostać zainicjowany w celu uniknięcia NRE.

(B) stosowanie wyraźne pole oporowe oraz zapewnienie bezpośredniego dostępu do niej (w celu uniknięcia wywoływania obciążenia leniwy posesją akcesor). Na przykład:

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); 
    }
}
Odpowiedział 19/12/2018 o 15:20
źródło użytkownik

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