Sdílet prostřednictvím


Dotazování a hledání entit

Toto téma popisuje různé způsoby, jak se můžete dotazovat na data pomocí Entity Frameworku, včetně jazyka LINQ a metody Find. Techniky uvedené v tomto tématu jsou rovnocenné pro modely vytvořené pomocí Code First a EF Designeru.

Hledání entit pomocí dotazu

DbSet a IDbSet implementují IQueryable, což lze použít jako výchozí bod pro zápis dotazu LINQ do databáze. Zde není vhodné místo pro podrobnou diskuzi o jazyce LINQ, uvádíme ale několik jednoduchých příkladů:

using (var context = new BloggingContext())
{
    // Query for all blogs with names starting with B
    var blogs = from b in context.Blogs
                   where b.Name.StartsWith("B")
                   select b;

    // Query for the Blog named ADO.NET Blog
    var blog = context.Blogs
                    .Where(b => b.Name == "ADO.NET Blog")
                    .FirstOrDefault();
}

Mějte na paměti, že DbSet a IDbSet vždy vytvářejí dotazy vůči databázi a vždy tedy budou zahrnovat dobu odezvy databáze, i když vrácené entity už existují v kontextu. Dotaz se provede vůči databázi, když:

  • Je výčtem příkazu foreach (C#) nebo For Each (Visual Basic).
  • Je výčtem operace kolekce, jako je ToArray, ToDictionary nebo ToList.
  • Operátory LINQ, jako First nebo Any, jsou uvedeny v nejkrajnější části dotazu.
  • Volají se následující metody: rozšiřující metoda Load pro DbSet, DbEntityEntry.Reload a Database.ExecuteSqlCommand.

Při vrácení výsledků z databáze jsou objekty, které neexistují v kontextu, připojeny ke kontextu. Pokud už objekt v kontextu je, vrátí se existující objekt (aktuální a původní hodnoty vlastností objektu v položce nejsou přepsány hodnotami databáze).

Když provedete dotaz, pak entity, které byly přidány do kontextu, ale ještě nebyly uloženy do databáze, nejsou vráceny jako součást sady výsledků. Pokud chcete získat data, která jsou v kontextu, přečtěte si článek Místní data.

Pokud dotaz nevrátí z databáze žádné řádky, bude výsledkem prázdná kolekce, nikoli null.

Hledání entit pomocí primárních klíčů

Metoda Find v DbSet používá k vyhledání entity sledované kontextem hodnotu primárního klíče. Pokud entita není v kontextu nalezena, odešle se dotaz do databáze, aby byla nalezena tam. Pokud entita není nalezena v kontextu ani v databázi, vrátí se hodnota null.

Find se liší od použití dotazu dvěma významnými způsoby:

  • Doba odezvy databáze vznikne jen v případě, že entita s daným klíčem není nalezena v kontextu.
  • Find vrátí entity, které jsou ve stavu Přidáno. To znamená, že Find vrátí entity, které byly přidány do kontextu, ale ještě nebyly uloženy do databáze.

Hledání entity podle primárního klíče

Následující kód ukazuje způsoby použití metody Find:

using (var context = new BloggingContext())
{
    // Will hit the database
    var blog = context.Blogs.Find(3);

    // Will return the same instance without hitting the database
    var blogAgain = context.Blogs.Find(3);

    context.Blogs.Add(new Blog { Id = -1 });

    // Will find the new blog even though it does not exist in the database
    var newBlog = context.Blogs.Find(-1);

    // Will find a User which has a string primary key
    var user = context.Users.Find("johndoe1987");
}

Hledání entity pomocí složeného primárního klíče

Entity Framework umožňuje, aby entity měly složené klíče – tedy klíče, které se skládají z více než jedné vlastnosti. Můžete mít například entitu BlogSettings, která reprezentuje nastavení uživatelů pro konkrétní blog. Protože uživatel by měl vždy jen jednu entitu BlogSettings pro každý blog, můžete se rozhodnout, aby byl primární klíč BlogSettings tvořen kombinací identifikátoru blogu (BlogId) a uživatelského jména (Username). Následující kód se pokusí najít BlogSettings s BlogId = 3 a Username = "johndoe1987":

using (var context = new BloggingContext())
{
    var settings = context.BlogSettings.Find(3, "johndoe1987");
}

Mějte na paměti, že pokud máte složené klíče, musíte k určení pořadí vlastností složeného klíče použít ColumnAttribute nebo rozhraní Fluent API. U volání metody Find se toto pořadí musí používat při určování hodnot, které tento klíč tvoří.