Účinný způsob, jak naplnit Entify rámcové dotaz s souvisejících objektů?

hlasů
0

Jsem pomocí EF pro sadu objektů a chtějí dotazovat jeden typ objektu s údaji odpovídajícími z dalších dvou tabulek. To je vypsat dotazu do XML výstupu. Zpočátku používá připojit, protože v původním datům každý zaměstnanec měl vždy 1+ instance Počítačový objektu (řešení # 2 níže), ale to není nutně pravda.

Pro účely zde, představte:

  • zaměstnanců objekt,
  • Každý zaměstnanec má EmployeeType (některé fixní položky) a
  • Každý zaměstnanec má nula nebo více počítačových objektů (typicky 0-3).
  • Každý počítač patří do jednoho zaměstnance, ne všichni zaměstnanci mají počítač.
  • Každý zaměstnanec má kritéria, na nichž je založen vyhledávání (například oddělení ).

Tak jsem viděl několik možných řešení:

  1. Použijte Employee.Computer.Load () ve smyčce, ale s 10,000 řádky, která způsobuje obrovské snížení výkonu.

  2. Použijte spojit v dotazu, ale to vynechá všechny zaměstnance , které nemají počítač .

  3. Používat LINQ k entity, ale to vypadá, že má režii č.1: Při nakládání s počítačem to dopadne databázi pro každý zaměstnance .

  4. Použít druhý dotaz (vše Computer y s odpovídajícími Computer.Employee.Division ), pak ve zaměstnanců smyčce, přidat libovolný počítač pro daného zaměstnance. Při implementaci tohoto, jsem zjistil, že právě běží druhý dotaz (s tolist () ) EF naplní správné Employee.Computer seznamy s objekty, které potřebuji.

Odtud # 4 načte data pouze s 2 databázi hity místo 10k + a EntityFramework skutečně třídí objekty a vytváří všechny vztahy.

Moje otázky :

  • S # 4, je skutečnost, že EF vyplní Employee.Computer seznamu něco, na které jsem se mohu spolehnout? Pokud ano, můžete ukázat, abych dokumentaci?
  • Existuje lepší způsob, než # 4?

UPDATE : No, prevít. Je nám líto, ale prostě jsem to podělal. Byl jsem se zaměřením na vztah k „Počítač“ stolu a minul, že jsem měl explicitní Employee.EmployeeTypeReference.Load () w / o první testování na nulu, takže v seznamu „Computer“ byl kompletní non-záležitost.

Jen jsem našel toto, když běží nějaké testy výkonu a přidáním roztoku Craig do mixu. Po pravdě řečeno, záznamy nejsou „zaměstnanci“ a „Počítače“, ale abstrakce, a já (podmíněně) zahrnují všechny oblasti ve výstupu XML, ale jsou malé: Name, ID (PK) a ID (FK) a int na „zaměstnance“ tabulky. Takže moje domněnka byla, že výkon by byl podobný, protože EF by vytvořit objekty moc těžší než projekce.

Každopádně, tady jsou výsledky wher dále jen „Uplynulý“ čas byl ten rozdíl, než tento dotaz a poté byla vytvořena výsledná XML.

  • Případ 1: Stejné jako # 2, ale s include () Prohlášení:

    list = ve.Employee.Include(Computer).Include(EmployeeType).Where(e => e.Division.ID == divId).OrderBy(e => e.Name);

    Uplynulý: 4,96, 5,05

  • Případ 2: Používá in-line load () :

    list = ve.Employee.Where(e => e.Division.ID == divId).OrderBy(e => e.Name);

    Uplynulá: 74,62

  • Případ 3: Stejné jako u # 4, ale s include () Prohlášení:

    list = from e in ve.Employee.Include(Computer).Include(EmployeeType) where e.Division.ID == divId orderby e.Name select e;

    Uplynulý: 4,91, 5,47

  • Případ 4: Použití pro in-line load () :

    list = from e in ve.Employee where e.Division.ID == divId orderby e.Name select e;

    Uplynulá: 74.20

  • Případ 5: Použití * zahrnout ( EmployeeType) a oddělený Computer dotaz, ať EF spolupracovník:

    elist = ve.Employee.Include(EmployeeType).Where(te => te.Division.ID == divId).OrderBy(e => e.Name).ToList(); alist = ve.Alias.Where(a => a.Employee.Division.ID == divId).ToList();

    Uplynulý: 4,50, 4,02

  • Případ 6: Craig náznak projekcí:

    elist = from te in ve.ThesaurusEntry where te.Division.ID==divID orderby te.Name select new { ID = te.ID, Name = te.Name, Type = te.EmployeeType.Name, Freq = te.Frequency, Aliases = from a in te.Alias select new { ID = a.ID, Name = a.Name } };

    Uplynulá: 0,73, 1,25

závěry

Zatížení () je drahé, takže použití include () nebo alespoň test s IsLoaded

Projekce je trochu únavné, ale výrazně rychleji než EF fix-up. [s tímto omezeným testováním na „úzké“ tabulkách]

Položena 26/08/2009 v 23:16
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
2

Domnívám se, že vám může indikovat, že vztahy mohou být pre-naložený

Dim employees = From emp in db.Employees.Include("Computer") _
                Select emp
Odpovězeno 27/08/2009 v 01:06
zdroj uživatelem

hlasů
1

Rob řešení bude fungovat (+1), ale pokud nepotřebujete všechna pole, řekněme zaměstnanců a počítače, tak bych důrazně doporučujeme projektování místo:

var q = from e in Context.Employees
        where e.Division.Id = divisionId
        select new
        {
            Name = e.Name,
            EmployeeType = e.EmployeeType.Description,
            ComputerIds = from c in e.Computers
                          select new 
                          {
                              Id = c.Id
                          }
        };

Zde dostanete vše, co potřebujete v jednom dotazu, ale nic víc : Všechna pole, které nepotřebujete nebudou vráceny.

Dalo by se pravděpodobně ještě vybrat do XElementsa jen uložit výsledný strom a nikoli ručně konverzi do formátu XML. Nezkoušel jsem to, ale zdá se, jako by to mělo fungovat.

Co se týče # 4, ano, můžete se spolehnout na to, ale je to vždy dobré zkontrolovat IsLoadedpřed voláním Load().

Odpovězeno 27/08/2009 v 14:17
zdroj uživatelem

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