Skocz do zawartości

[Sfera] wyszukiwanie asortymentu i stanu magazynowego - optymalizacja

Polecane posty

Dzień dobry,
w jaki sposób można zoptymalizować poniższy kod odczytujący wybrane dane z całego asortymentu na konkretnym magazynie?
Do każdego produktu (asortymentu) potrzebuję odczytywać symbol produktu, nazwę, nazwę grupy oraz stan magazynowy i kod EAN.
Obecnie odczytuję te dane tak jak podaję poniżej, ale przy ok. 2 tysiącach produktów trwa to u mnie ponad 20 min i chciałbym ten czas skrócić, szczególnie że produktów będzie więcej.

 

IAsortymenty asortyment = _sfera.PodajObiektTypu<IAsortymenty>();
IQueryable<Asortyment> calyAsortyment = asortyment.Dane.Wszystkie();
foreach (Asortyment asort in calyAsortyment)
{
    string symbol = asort.Symbol;
    string nazwaGrupy = "";
    if (asort.Grupa != null)
    {
        nazwaGrupy = asort.Grupa.Nazwa;
    }
    ICollection<JednostkaMiaryAsortymentu> jedn = asort.JednostkiMiar;
    foreach (JednostkaMiaryAsortymentu jm in jedn)
    {
        if (jm.KodyKreskowe != null)
        {
            KodKreskowy kodKr = jm.KodyKreskowe.FirstOrDefault();
        }
    }

    Magazyn mag = _sfera.PodajObiektTypu<IMagazyny>().Dane.Wszystkie().Where(m => m.Symbol == "MAG").FirstOrDefault();
    StanMagazynowy stan = new StanMagazynowy();
    ICollection<StanMagazynowy> stanyMagAs = mag.StanyMagazynowe;
    stan = stanyMagAs.Where(x => x.Asortyment.Symbol.ToLower().Equals(symbol.ToLower()) && x.Asortyment.Rodzaj.CzyTowar() == true).FirstOrDefault();
    if (stan != null)
    {
        decimal iloscDostepna = stan.IloscDostepna;
    }
}

 

Link to postu

Pański kod wykonuje operację pobrania wszystkich danych asortymentów w momencie pierwszego wejścia w pierwszą pętlę foreach (proszę sobie to sprawdzić np. profilerem SQL). Więc pobiera Pan mnóstwo niepotrzebnych Panu danych co spowalnia cały proces. Dodatkowo wewnątrz pętli dane powiązanych obiektów (grupa, jednostki miar, stany magazynowe) są dociągane z bazy danych mechanizmem "leniwego doładowywania" (czyli dane są doładowane wtedy kiedy kod się do nich próbuje dostać). W takim przypadku jeśli ma Pan 2000+ asortymentów to 2000+ razy wykonuje się w Pana kodzie zapytanie o grupę asortymentu, jednostki miar i tak dalej (to też będzie widać na profilerze). Kod należałoby przerobić na jedno zapytanie LINQ, które pobiera tylko te dane, które są potrzebne.

Link to postu

Dzięki za podpowiedzi.

Wychodzi na to, że się udało. Poniżej kod, gdyby ktoś kiedyś potrzebował.

IAsortymenty asortymentProd = _sfera.PodajObiektTypu<IAsortymenty>();
var wszystkie = asortymentProd.Dane.Wszystkie().Select(x => new
{
	x.Nazwa,
	x.Symbol,
	NazwaGrupy = x.Grupa.Nazwa,
	x.Rodzaj,
	StanDostepny = x.StanyMagazynowe.Where(s => s.Magazyn.Symbol == "MAG").Select(s => s.IloscDostepna),
	Ean = x.PodstawowaJednostkaMiaryAsortymentu.KodyKreskowe.Select(k => k.Kod).FirstOrDefault(),
});

 

Link to postu
×
×
  • Dodaj nową pozycję...