Wykonywanie zapytań i znajdowanie jednostek

W tym temacie opisano różne sposoby wykonywania zapytań o dane przy użyciu rozwiązania Entity Framework, w tym zapytania LINQ i metody Find. Techniki przedstawione w tym temacie dotyczą modeli utworzonych przy użyciu podejścia „najpierw kod” i narzędzia EF Designer.

Znajdowanie jednostek przy użyciu zapytania

Klasa DbSet i interfejs IDbSet implementują interfejs IQueryable, dlatego mogą być używane jako punkt wyjścia do pisania zapytania LINQ względem bazy danych. Nie jest to właściwe miejsce do szczegółowej dyskusji na temat zapytania LINQ, ale oto kilka prostych przykładów:

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();
}

Należy pamiętać, że klasa DbSet i interfejs IDbSet zawsze tworzą zapytania względem bazy danych i zawsze będą obejmować rundy do bazy danych, nawet jeśli jednostki zwrócone już istnieją w kontekście. Zapytanie jest wykonywane względem bazy danych, gdy:

  • Jest wyliczane przez instrukcję foreach (C#) lub For Each (Visual Basic).
  • Jest wyliczane przez operację kolekcji, taką jak ToArray, ToDictionary lub ToList.
  • Operatory 0LINQ, takie jak First lub Any, są określone w najbardziej zewnętrznej części zapytania.
  • Są wywoływane następujące metody: metoda rozszerzenia Load w klasie DbSet, DbEntityEntry.Reload i Database.ExecuteSqlCommand.

Gdy wyniki są zwracane z bazy danych, obiekty, które nie istnieją w kontekście, są dołączone do kontekstu. Jeśli obiekt znajduje się już w kontekście, jest zwracany istniejący obiekt (bieżące i oryginalne wartości właściwości obiektu we wpisie nie są zastępowane wartościami z bazy danych).

Podczas wykonywania zapytania jednostki, które zostały dodane do kontekstu, ale nie zostały jeszcze zapisane w bazie danych, nie są zwracane jako część zestawu wyników. Aby uzyskać dane, które są w kontekście, zobacz Dane lokalne.

Jeśli zapytanie nie zwraca żadnych wierszy z bazy danych, wynikiem będzie pusta kolekcja, a nie null.

Znajdowanie jednostek przy użyciu kluczy podstawowych

Metoda Find w klasie DbSet używa wartości klucza podstawowego do próby znalezienia jednostki śledzonej przez kontekst. Jeśli jednostka nie zostanie znaleziona w kontekście, do bazy danych zostanie wysłane zapytanie mające na celu znalezienie jednostki tam. Jeśli jednostka nie zostanie znaleziona w kontekście ani w bazie danych, zwracana jest wartość null.

Metoda Find różni się od używania zapytania na dwa istotne sposoby:

  • Rundy do bazy danych zostaną wykonane tylko wtedy, gdy jednostka z danym kluczem nie zostanie znaleziona w kontekście.
  • Metoda Find zwróci jednostki, które znajdują się w stanie Dodano. Oznacza to, że metoda Find zwróci jednostki, które zostały dodane do kontekstu, ale nie zostały jeszcze zapisane w bazie danych.

Znajdowanie jednostki według klucza podstawowego

Poniższy kod przedstawia niektóre zastosowania 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");
}

Znajdowanie jednostki według złożonego klucza podstawowego

Rozwiązanie Entity Framework umożliwia jednostkom posiadanie kluczy złożonych — czyli kluczy składających się z więcej niż jednej właściwości. Na przykład możesz mieć jednostkę BlogSettings, która reprezentuje ustawienia użytkowników dla określonego bloga. Ponieważ użytkownik będzie miał tylko jeden element BlogSettings dla każdego bloga, możesz wybrać, aby klucz podstawowy jednostki BlogSettings składał się z kombinacji wartości BlogId i Username. Poniższy kod próbuje znaleźć element BlogSettings z BlogId = 3 i Username = "johndoe1987":

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

Pamiętaj, że jeśli masz klucze złożone, musisz użyć atrybutu ColumnAttribute lub płynnego interfejsu API, aby określić kolejność właściwości klucza złożonego. Wywołanie metody Find musi używać tej kolejności podczas określania wartości, które tworzą klucz.