Jak nejefektivněji ověřit existenci záznamu před vložením? (EF)   zodpovězená otázka

Entity Framework, Databáze

Zkoušel jsem dva přístupy (odkomentovaný, zakomentovaný) viz. kód:


        public int Exist(DataSet dataSet)
        {

            int id;
            using (var db = new DbContext())
            {

                id= db.Database.SqlQuery<short>("select Id from DataSets where Name=@p0 and Version=@p1",dataSet.Name, dataSet.Version).FirstOrDefault();
                //id = db.DataSets.Where(p => p.Name == dataSet.Name && p.Version ==  dataSet.Version).Select(p => p.Id).FirstOrDefault();

            }

            return id;
        }

Měřením jsem zjistil, že použítí SqlQuery() je asi o polovinu rychlejší. Měřil jsem počet tiků pomocí Stopwatch.

Je to způsobeno tím, že výsledek SqlQuery není "sledován" contextem?

Je tedy lepší používat SqlQuery v případě, že nepotřebuji mít výsledek v contextu nebo když potřebuji jen jeden sloupec z tabulky?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Můžete zkusit

if(db.DataSets.Any(p =>p.Name == dataSet.Name && p.Version ==  dataSet.Version)){
}
nahlásit spamnahlásit spam 0 odpovědětodpovědět

V případě existence, potřebuji vrátit Id, takže tohle mi asi nepomůže.

Spíš jsem chtěl znát rozdíl mezi SqlQuery a LINQem.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

První případ (SqlQuery) obchází EF a bude mít tedy stejnou výkonnost jako přímé volání např. přes ADO.NET SqlCommand.

Druhý případ je volání přes EF, které sebou samozřejmě nese navíc režii na transformaci LINQ dotazu do SQL a transformaci výsledků dotazu na objekty (v tomto případě na int).

Tuším, že se někde uvádělo, že je to přibližně 30%, ale u takto jednoduchého dotazu to bude klidně víc (obecně doba režie EF je nezávislá na době vlastního zpracování dotazu na SQL).

Hádám ale, že oba časy v tomto případě nebudou jinak závratné.

Obecný postup při používání EF je takový, že datovou vrstvu a logiku implementujete s využitím EF (tedy druhá varianta). A teprve později při testování (někdy třeba až v produkci), když toto konkrétní volání identifikujete jako výkoností bottleneck dané uživatelské funkce (protože se třeba volá v cyklu hodněkrát), přistoupíte k nějaké optimalizaci.

Jestli bude výsledkem optimalizace konkrétně přepsání pouze tohoto jednoho dotazu na první variantu bude záviset na dané uživatelské funkci.

Pokud výkoností problém neodhalíte testováním nemá cenu provádět pre-optimalizaci nepoužíváním EF, protože nejste schopen dopředu odhadnout, který dotaz bude problém dělat a jen by to zbytečně vedlo na méně čitelný a měně udržovatelný kód.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Super, děkuji za vysvětlení.

Co se týče té výkonnosti, tak se mi zdá vhodné v mém případě to řešit už teď.

Parsuji xml, které mi chodí POSTem, klidně i několikrát za vteřinu. Parsuji ho zhruba do 20ti tabulek s tím, že musím ověřovat existence záznamů v číselnících apod.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pro takový scénář je nejefektivnější (ale ne vždy je to tak nutně potřeba), poslat celé XML přímo do uložené procedury na SQL serveru (podpora XML je v SQL Serveru od verze 2005) a v té ho teprve najednou zpracovat. To by pak bylo na jedno volání do SQL, což by mohl být velký výkonnostní rozdíl.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback