Tworzenie dostawcy bazy danych

Aby uzyskać informacje na temat pisania dostawcy bazy danych Platformy Entity Framework Core, zobacz Artykuł Więc chcesz napisać dostawcę platformy EF Core przez Arthura Vickersa.

Uwaga

Te wpisy nie zostały zaktualizowane od wersji EF Core 1.1 i od tego czasu nastąpiły znaczące zmiany. Problem 681 śledzi aktualizacje tej dokumentacji.

Baza kodu platformy EF Core jest bazą danych typu open source i zawiera kilku dostawców baz danych, których można użyć jako odwołania. Kod źródłowy można znaleźć pod adresem https://github.com/dotnet/efcore. Warto również przyjrzeć się kodowi dla powszechnie używanych dostawców innych firm, takich jak Npgsql, Pomelo MySQL i SQL Server Compact. W szczególności te projekty są konfigurowane w celu rozszerzania i uruchamiania testów funkcjonalnych publikowanych w programie NuGet. Ten rodzaj konfiguracji jest zdecydowanie zalecany.

Aktualizowanie zmian dostawcy

Począwszy od pracy po wersji 2.1, utworzyliśmy dziennik zmian, które mogą wymagać odpowiednich zmian w kodzie dostawcy. Ma to pomóc podczas aktualizowania istniejącego dostawcy do pracy z nową wersją platformy EF Core.

Przed wersją 2.1 użyliśmy providers-beware etykiet i providers-fyi w naszych problemach z usługą GitHub i żądaniami ściągnięcia w podobnym celu. Będziemy nadal używać tych etykiet w przypadku problemów, aby wskazać, które elementy robocze w danej wersji mogą również wymagać pracy wykonywanej przez dostawców. Etykieta providers-beware zazwyczaj oznacza, że implementacja elementu roboczego może spowodować przerwanie dostawców, podczas gdy etykieta providers-fyi zazwyczaj oznacza, że dostawcy nie będą przerywani, ale kod może być mimo to zmieniony, aby umożliwić korzystanie z nowych funkcji.

Sugerowane nazewnictwo dostawców innych firm

Zalecamy użycie następującego nazewnictwa pakietów NuGet. Jest to zgodne z nazwami pakietów dostarczanych przez zespół platformy EF Core.

<Optional project/company name>.EntityFrameworkCore.<Database engine name>

Przykład:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Npgsql.EntityFrameworkCore.PostgreSQL
  • EntityFrameworkCore.SqlServerCompact40

Testy specyfikacji programu EF Core

Program EF Core udostępnia projekt zestawu testów specyfikacji, który zachęcamy wszystkich dostawców do wdrożenia. Projekt zawiera testy, które zapewniają poprawne działanie dostawcy, np. wykonując różne zapytania LINQ i upewniając się, że zwracane są prawidłowe wyniki. Ten zestaw testów jest używany przez własnych dostawców programu EF Core (takich jak SQL Server, SQLite i Azure Cosmos DB) jako podstawowy mechanizm testowania regresji i są stale aktualizowani i ulepszani w miarę dodawania nowych funkcji do platformy EF Core. Implementując te testy dla innych dostawców innych firm, możesz upewnić się, że dostawca bazy danych działa poprawnie i implementuje wszystkie najnowsze funkcje platformy EF Core. Należy pamiętać, że zestaw testów jest dość duży, ponieważ obejmuje cały zestaw funkcji platformy EF Core; nie musisz implementować wszystkiego - idealnie dobrze jest wybrać niektóre klasy testowe i przyrostowo poprawić zasięg z czasem.

Aby rozpocząć korzystanie z testów specyfikacji, wykonaj następujące kroki:

  • Utwórz projekt testowy xUnit w rozwiązaniu dostawcy. Sugerujemy nazwę <Provider>.FunctionalTests spójności, więc jeśli dostawca nosi nazwę AcmeSoftware.EntityFramework.AcmeDb, wywołaj projekt AcmeSoftware.EntityFramework.AcmeDb.FunctionalTeststestowy .
  • W nowym projekcie testowym zapoznaj się z testami specyfikacji ef, które są publikowane jako zwykłe pakiety Nuget. W przypadku dostawców relacyjnych zestaw testów specyfikacji to Microsoft.EntityFrameworkCore.Relational.Specification.Tests, dla dostawcy nierelacyjnego, należy użyć elementu Microsoft.EntityFrameworkCore.Specification.Tests.
  • Wybierz klasę testową z testów specyfikacji ef i rozszerz ją z odpowiedniej klasy testowej we własnym projekcie. Dostępne klasy testów można zobaczyć w kodzie źródłowym ef. Klasa powinna być nazwana na podstawie klasy testowej EF z nazwą dostawcy wstawioną tam, gdzie jest to konieczne. Na przykład NorthwindWhereQueryRelationalTestBase (co jest dobrym miejscem do rozpoczęcia) zostałoby rozszerzone o NorthwindWhereQueryAcmeDbTestwartość .
  • Na samym początku będziesz mieć trochę infrastruktury testowej do zaimplementowania — po wykonaniu tego zadania staną się łatwiejsze. Na przykład NorthwindWhereQueryAcmeDbTest należy zaimplementować NorthwindWhereQueryAcmeDbFixtureskrypt , który będzie wymagał skryptu AcmeDbNorthwindTestStoreFactoryNorthwind.sql, aby zainicjować wersję bazy danych NorthwindDb w wersji bazy danych Northwind. Zdecydowanie zalecamy pozostawienie w pobliżu innego zestawu testowego dostawcy platformy EF Core i przestrzeganie tego, co robi. Na przykład implementacja programu SQL Server testów specyfikacji jest widoczna tutaj.
  • Po zakończeniu infrastruktury dla klasy testowej zaczniesz widzieć na nim zielone testy. Możesz zbadać testy zakończone niepowodzeniem lub tymczasowo pominąć je w celu późniejszego zbadania. W ten sposób można dodawać coraz więcej klas testowych.
  • W pewnym momencie po rozszerzeniu większości nadrzędnych klas testowych można również utworzyć AcmeDbComplianceTestelement , który rozszerza element RelationalComplianceTestBase. Ta klasa testowa zakończy się niepowodzeniem, jeśli własny projekt testowy nie rozszerzy klasy testowej EF Core — jest to doskonały sposób na sprawdzenie, czy zestaw testów został ukończony, a także czy platforma EF dodała nową klasę testową w nowej wersji. Możesz również zrezygnować z rozszerzania określonych klas testowych, jeśli nie są gotowe (lub nie są odpowiednie).

Asercji SQL

Podczas implementowania testów specyfikacji można dodatkowo potwierdzić język SQL generowany przez program EF Core. Nie jest to obowiązkowe: implementacja testu specyfikacji sprawdza już, czy dostawca zwrócił oczekiwane wiersze z bazy danych, więc jeśli przejdzie pomyślnie, dostawca prawdopodobnie wykonuje odpowiednie czynności. Jednak twierdzenie, że sql jest to, czego oczekujesz, może dodać dodatkowe pokrycie w niektórych przypadkach, szczególnie w przypadku, gdy część konstrukcji SQL jest używana, która jest specyficzna dla bazy danych.

Na przykład poniżej przedstawiono Where_simple test w klasie testowej NorthwindWhereQuerySqlServerTest :

public override async Task Where_simple(bool async)
{
    await base.Where_simple(async);

    AssertSql(
        @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
FROM [Customers] AS [c]
WHERE [c].[City] = N'London'");
}

Wywołanie podstawowe uruchamia test specyfikacji, który wykonuje zapytanie LINQ i sprawdza, czy wyniki są poprawne. Ponadto gwarantuje, AssertSql że baza danych SQL jest zgodna z punktem odniesienia uwzględnionym w teście.

Sprawdzanie niepowodzeń asercji SQL

Jeśli asercja SQL nie powiedzie się, narzędzie xunit zwykle zgłasza tylko fragment kodu SQL, który nie był zgodny. Aby wyświetlić pełną pełną pełną pulę danych bazowych wygenerowaną przez dostawcę, możesz uzyskać dane wyjściowe infrastruktury testowej, gdy test zakończy się niepowodzeniem, aby można było go sprawdzić i ewentualnie zastąpić stary. W tym celu należy przekazać ITestOutputHelper element xunit do TestSqlLoggerFactory urządzenia testowego:

public NorthwindWhereQuerySqlServerTest(
    NorthwindQuerySqlServerFixture<NoopModelCustomizer> fixture,
    ITestOutputHelper testOutputHelper)
    : base(fixture)
{
    ClearLog();
    Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}

W zestawach testów platformy EF Core zwykle utrzymujemy komentarz w powyższym wierszu w konstruktorze, dzięki czemu możemy łatwo usunąć komentarz za każdym razem, gdy aseracja SQL zakończy się niepowodzeniem.

Zbiorcze aktualizowanie punktów odniesienia

Jeśli używasz asercji SQL dużo, będziesz mieć wiele punktów odniesienia SQL w zestawie testów. W niektórych przypadkach niewielka zmiana — zarówno u dostawcy, jak i w samym programie EF Core — może spowodować, że duża liczba tych asercji nie powiedzie się z jakiegoś powodu, np. nawiasy zostały dodane gdzieś. W takim przypadku ręczne poprawianie wszystkich punktów odniesienia, których dotyczy problem, może być bardzo żmudnym i czasochłonnym procesem.

Infrastruktura testowa platformy EF Core ma funkcję, która automatycznie aktualizuje wszystkie nieudane punkty odniesienia przy użyciu nowych. Wystarczy ustawić zmienną EF_TEST_REWRITE_BASELINES środowiskową na 1 i uruchomić testy, a pliki źródłowe testów powinny zostać zaktualizowane. Zaleca się zatwierdzenie przed wykonaniem tej czynności, a następnie sprawdzenie różnic w testach za pomocą narzędzia Git, aby upewnić się, że nowe punkty odniesienia mają sens. Po osiągnięciu zadowolenia możesz również zatwierdzić te zmiany.