Procedury składowane są integralną częścią każdej bazy danych MS SQL. Są idealne do opakowania skomplikowanego kodu SQL w obiekt bazy danych, którego możemy ponownie użyć. Jak wykonać procedurę składowaną, która zwraca dane w Entity Framework Core 5? W moim ostatnim poście: Wykonanie procedury składowanej w Entity Framework Core pokazałem, jak uruchomić procedurę składowaną. Jednak pobranie danych to już zupełnie inna historia. Spójrzmy.
Dodanie procedury składowanej
Przede wszystkim musimy dodać procedurę składowaną. Najlepszym sposobem na to jest dodanie migracji bazy danych z odpowiednim kodem SQL. Zacznijmy od dodania migracji za pomocą polecenia narzędzia globalnego EF Core:
dotnet ef migrations add spGetGuestsForDate
To wygeneruje migrację, w której możemy umieścić nasz SQL. Zobaczmy, jak to może wyglądać:
public partial class spGetGuestsForDate : Migration { protected override void Up(MigrationBuilder migrationBuilder) { var sql = @" IF OBJECT_ID('GetGuestsForDate', 'P') IS NOT NULL DROP PROC GetGuestsForDate GO CREATE PROCEDURE [dbo].[GetGuestsForDate] @StartDate varchar(20) AS BEGIN SET NOCOUNT ON; SELECT p.Forename, p.Surname, p.TelNo, r.[From], r.[To], ro.Number As RoomNumber FROM Profiles p JOIN Reservations r ON p.ReservationId = p.ReservationId JOIN Rooms ro ON r.RoomId = ro.Id WHERE CAST([From] AS date) = CONVERT(date, @StartDate, 105) END"; migrationBuilder.Sql(sql); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.Sql(@"DROP PROC GetGuestsForDate"); } }
Jest to prosty kod SQL, który najpierw sprawdza, czy procedura istnieje, a jeśli tak, usuwa ją. Następnie tworzy nową procedurę o nazwie GetGuestsForDate
, która pobierze wszystkich przybywających gości danego dnia.
Kiedy migracja zostanie wykonana na bazie danych, ta procedura składowana będzie już istniała, co możemy zobaczyć tutaj:
Pobranie danych za pomocą procedury skłdowanej
Kiedy przyjrzysz się bliżej SQL, zauważysz, że spodziewamy się otrzymać listę gości z polami: Forename
, Surname
, TelNo
, From
, To
and RoomNumber
. Aby użyć procedury składowanej do zapytania bazy danych i zmapowania wyników na encje, musimy dodać odpowiednią encję. W moim przypadku dodam GuestArrival
, który wygląda tak:
[Keyless] public class GuestArrival { public string Forename { get; set; } public string Surname { get; set; } public string TelNo { get; set; } public DateTime From { get; set; } public DateTime To { get; set; } public int RoomNumber { get; set; } }
Ta klasa zawiera wszystkie kolumny, które chcę zmapować, a także ma atrybut [Keyless]
. Encje bez klucza mają większość możliwości mapowania tak jak zwykłe encje, ale nie są śledzone pod kątem zmian w DbContext. Oznacza to również, że nie będziemy w stanie wykonać wstawiania, aktualizowania ani usuwania takiego obiektu.
Musimy również dodać DbSet do naszego kontekstu PrimeDbContext
.
public class PrimeDbContext : DbContext { public PrimeDbContext(DbContextOptions<PrimeDbContext> options) : base(options) { } // from stored procedures public virtual DbSet<GuestArrival> GuestArrivals { get; set; } }
Teraz możemy iść dalej i użyć go. Oto, jak możemy wykonać tą procedurę składowaną:
var guests = primeDbContext.GuestArrivals.FromSqlInterpolated($"GetGuestsForDate '{date}'").ToList();
A jeśli umieszczę go w moim projekcie API, zmapuje wyniki na encje, to zobaczę taki wynik:
Wspomnę tutaj, ze używam parametru date
w formacie dd-mm-rrrr
, który przekazuję jako ciąg znaków do mojej procedury składowanej. Następnie w środku używam CONVERT(data, @StartDate, 105)
, gdzie 105 to format daty, który zamierzam konwertować. Więcej obsługiwanych formatów znajdziesz w tym artykule. Inną możliwością jest użycie parametru SqlParameter z typem danych Date, jednak formatowanie i przekazywanie daty może być kłopotliwe, więc wybrałem taki sposób.
Podsumowanie
Entity Framework Core może łatwo obsługiwać dane pobrane przez procedury składowane. Nie ma dedykowanej metody uruchamiania procedury, ale można ją uruchomić jako standardowy surowy kod SQL na kolekcji DbSet. Jeśli jednak interesuje Cię tylko wykonanie procedury składowanej, nie potrzebujesz do tego dedykowanego DbSet. Możesz sprawdzić szczegóły w moim poprzednim poście: Wykonanie procedury składowanej w Entity Framework Core.
Co więcej, możesz obsługiwać dodawanie lub aktualizowanie procedur składowanych za pomocą migracji EF Core, co oznacza, że wszystkie wymagane prace można wykonać za pomocą EF Core.
Cały opublikowany tutaj kod można znaleźć na moim GitHubie, możesz z nim eksperymentować do woli.
Pozdrawiam!