Łańcuchy połączeń i modele

W tym artykule opisano, w jaki sposób program Entity Framework odnajduje połączenie z bazą danych do użycia i jak go zmienić. Modele utworzone za pomocą funkcji Code First i EF Designer są omówione.

Ostrzeżenie

W tym artykule jest używana lokalna baza danych, która nie wymaga uwierzytelnienia użytkownika. Aplikacje produkcyjne powinny korzystać z najbezpieczniejszego dostępnego przepływu uwierzytelniania. Aby uzyskać więcej informacji na temat uwierzytelniania dla wdrożonych aplikacji testowych i produkcyjnych, zobacz Bezpieczne przepływy uwierzytelniania.

Zazwyczaj aplikacja platformy Entity Framework używa klasy pochodnej z klasy DbContext. Ta klasa pochodna wywołuje jeden z konstruktorów w podstawowej klasie DbContext, aby kontrolować:

  • Sposób nawiązywania połączenia kontekstu z bazą danych, to znaczy, jak ciąg połączenia jest znajdowany i używany.
  • Niezależnie od tego, czy kontekst oblicza model przy użyciu funkcji Code First, czy ładuje model utworzony za pomocą projektanta EF.
  • Dodatkowe opcje zaawansowane

W poniższych fragmentach przedstawiono niektóre sposoby użycia konstruktorów DbContext.

Użycie Code First z konwencją połączenia ustawianą domyślnie

Jeśli nie zrobiono żadnej innej konfiguracji w aplikacji, wywołanie konstruktora bez parametrów w obiekcie DbContext spowoduje uruchomienie elementu DbContext w trybie Code First z połączeniem bazy danych utworzonym zgodnie z konwencją. Na przykład:

namespace Demo.EF
{
    public class BloggingContext : DbContext
    {
        public BloggingContext()
        // C# will call base class parameterless constructor by default
        {
        }
    }
}

W tym przykładzie DbContext używa kwalifikowanej nazwy przestrzeni nazw klasy pochodnego kontekstu — Demo.EF.BloggingContext — jako nazwy bazy danych i tworzy ciąg połączeniowy dla tej bazy danych przy użyciu programu SQL Express lub LocalDB. Jeśli oba te elementy zostaną zainstalowane, zostanie użyta usługa SQL Express.

Program Visual Studio 2010 domyślnie obejmuje program SQL Express, a program Visual Studio 2012 lub nowszy zawiera bazę danych LocalDB. Podczas instalacji pakiet NuGet EntityFramework sprawdza, który serwer bazy danych jest dostępny. Pakiet NuGet zaktualizuje następnie plik konfiguracji, ustawiając domyślny serwer bazy danych używany przez program Code First podczas tworzenia połączenia według konwencji. Jeśli program SQL Express jest uruchomiony, zostanie użyty. Jeśli usługa SQL Express nie jest dostępna, baza danych LocalDB zostanie zarejestrowana jako domyślna. W pliku konfiguracji nie są wprowadzane żadne zmiany, jeśli zawiera już ustawienie dla domyślnej fabryki połączeń.

Korzystanie z Code First z połączeniem według konwencji i określoną nazwą bazy danych

Jeśli nie wykonano żadnej innej konfiguracji w aplikacji, to wywołanie konstruktora ciągu w DbContext z nazwą bazy danych, której chcesz użyć, spowoduje, że DbContext uruchomi się w trybie Code First z połączeniem do bazy danych utworzonym zgodnie z konwencją do bazy danych o tej nazwie. Na przykład:

public class BloggingContext : DbContext
{
    public BloggingContext()
        : base("BloggingDatabase")
    {
    }
}

W tym przykładzie dbContext używa nazwy bazy danych "BloggingDatabase" i tworzy parametry połączenia dla tej bazy danych przy użyciu programu SQL Express (zainstalowanego z programem Visual Studio 2010) lub LocalDB (zainstalowanego w programie Visual Studio 2012). Jeśli oba te elementy zostaną zainstalowane, zostanie użyta usługa SQL Express.

Użyj Code First z parametrem połączenia w pliku app.config/web.config

Możesz umieścić parametry połączenia w pliku app.config lub web.config. Na przykład:

<configuration>
  <connectionStrings>
    <add name="BloggingCompactDatabase"
         providerName="System.Data.SqlServerCe.4.0"
         connectionString="Data Source=Blogging.sdf"/>
  </connectionStrings>
</configuration>

Jest to prosty sposób informowania dbContext o używaniu serwera bazy danych innego niż SQL Express lub LocalDB — w powyższym przykładzie określono bazę danych SQL Server Compact Edition.

Jeśli nazwa ciągu połączenia jest zgodna z nazwą twojego kontekstu (z kwalifikacją przestrzeni nazw lub bez niej), zostanie znaleziona przez DbContext, gdy jest używany konstruktor bez parametrów. Jeśli nazwa parametry połączenia różni się od nazwy kontekstu, możesz poinformować DbContext o użyciu tego połączenia w trybie Code First, przekazując nazwę parametry połączenia do konstruktora DbContext. Na przykład:

public class BloggingContext : DbContext
{
    public BloggingContext()
        : base("BloggingCompactDatabase")
    {
    }
}

Alternatywnie, możesz użyć formatu "name=<nazwa ciągu połączenia>" dla ciągu przekazanego do konstruktora DbContext. Na przykład:

public class BloggingContext : DbContext
{
    public BloggingContext()
        : base("name=BloggingCompactDatabase")
    {
    }
}

Ten formularz jasno określa, że oczekujesz, iż parametry połączenia zostaną znalezione w pliku konfiguracyjnym. Jeśli nie zostanie znaleziony ciąg połączenia o podanej nazwie, zostanie zgłoszony wyjątek.

Database/Model First z ciągiem połączenia w plikach app.config/web.config

Modele utworzone za pomocą narzędzia EF Designer różnią się od modelu Code First, ponieważ model już istnieje i nie jest generowany na podstawie kodu po uruchomieniu aplikacji. Model zazwyczaj istnieje jako plik EDMX w projekcie.

Projektant doda parametry połączenia EF do pliku app.config lub web.config. Ten ciąg połączenia jest wyjątkowy, ponieważ zawiera informacje o tym, jak znaleźć informacje w pliku EDMX. Na przykład:

<configuration>  
  <connectionStrings>  
    <add name="Northwind_Entities"  
         connectionString="metadata=res://*/Northwind.csdl|  
                                    res://*/Northwind.ssdl|  
                                    res://*/Northwind.msl;  
                           provider=System.Data.SqlClient;  
                           provider connection string=  
                               &quot;Data Source=.\sqlexpress;  
                                     Initial Catalog=Northwind;  
                                     Integrated Security=True;  
                                     MultipleActiveResultSets=True&quot;"  
         providerName="System.Data.EntityClient"/>  
  </connectionStrings>  
</configuration>

Projektant EF wygeneruje również kod, który nakazuje DbContext użycie tego połączenia, przekazując nazwę łańcucha połączenia do konstruktora DbContext. Na przykład:

public class NorthwindContext : DbContext
{
    public NorthwindContext()
        : base("name=Northwind_Entities")
    {
    }
}

DbContext rozpoznaje, że należy załadować istniejący model (zamiast używania Code First do jego wygenerowania z kodu), ponieważ parametry połączenia to parametry połączenia EF zawierające szczegóły modelu do użycia.

Inne opcje konstruktora DbContext

Klasa DbContext zawiera inne konstruktory i wzorce użycia, które umożliwiają wykonywanie bardziej zaawansowanych scenariuszy. Oto niektóre z następujących elementów:

  • Możesz użyć klasy DbModelBuilder do utworzenia modelu Code First bez tworzenia wystąpienia DbContext. Wynikiem tego jest obiekt DbModel. Następnie możesz przekazać ten obiekt DbModel do jednego z konstruktorów DbContext, gdy będziesz gotowy do utworzenia wystąpienia DbContext.
  • Można przekazać pełny ciąg połączenia do DbContext zamiast tylko nazwy bazy danych lub ciągu połączenia. Domyślnie ten ciąg połączenia jest używany z dostawcą System.Data.SqlClient; można to zmienić, ustawiając inną implementację IConnectionFactory w kontekście za pomocą Database.DefaultConnectionFactory.
  • Możesz użyć istniejącego obiektu DbConnection, przekazując go do konstruktora DbContext. Jeśli obiekt połączenia jest wystąpieniem entityConnection, model określony w połączeniu będzie używany zamiast obliczania modelu przy użyciu funkcji Code First. Jeśli obiekt jest wystąpieniem innego typu, na przykład SqlConnection, kontekst go użyje w trybie Code First.
  • Istniejący obiekt ObjectContext można przekazać do konstruktora DbContext, aby utworzyć obiekt DbContext opakowujący istniejący kontekst. Może to być używane w przypadku istniejących aplikacji korzystających z obiektu ObjectContext, ale które chcą korzystać z obiektu DbContext w niektórych częściach aplikacji.