GitHub Codespaces je plně nakonfigurované vývojové prostředí postavené na Visual Studio Code, které lze spustit v prostředí hostovaném v cloudu a přistupovat k němu prostřednictvím webového prohlížeče. Podporuje repozitáře Git, rozšíření a integrované příkazové rozhraní, takže můžete upravovat, spouštět a testovat kód z jakéhokoli zařízení. Visual Studio pro Mac a Windows je vhodné pro vývoj většiny typů aplikací, včetně konzolových aplikací, webových stránek, webových služeb, desktopových a mobilních aplikací. Pro kompilaci aplikací pro operační systémy Apple, jako je iOS, musíte mít Xcode, které funguje pouze na macOS.

Visual Studio 2022 pro Windows je ideální pro vývoj aplikací na Windows 10 a novější verze. Umožňuje vývoj nejen desktopových a mobilních aplikací, ale i aplikací pro serverové prostředí. Když používáte Visual Studio 2022 pro Windows pro vývoj aplikací na platformu .NET MAUI (cross-platform mobilní aplikace), budete potřebovat i macOS a Xcode k samotné kompilaci kódu. V případě Windows musíte mít verzi 10.1909 nebo novější, případně Windows Server 2016 a novější. Verze 17.4 Visual Studio 2022 pro Windows poprvé podporuje nativní Arm64. Při vývoji aplikací na Windows by mělo být zajištěno, že hardware odpovídá požadavkům na 64-bitovou architekturu.

Pro vývoj a testování kódu, který je součástí této knihy, jsem použil následující hardware: laptop HP Spectre (Intel), desktop Apple Silicon Mac mini (M1) a desktop Raspberry Pi 400 (ARM v8). Co se týče softwaru, použil jsem Visual Studio Code na macOS, Windows 11 a Ubuntu 64-bit na Raspberry Pi 400. Na Windows jsem použil Visual Studio 2022 pro Windows a na Macu Visual Studio 2022 pro Mac. Rozdíly mezi těmito platformami dávají vývojáři lepší porozumění výzvám, které souvisejí s multiplatformním vývojem.

Pokud máte přístup k různým hardwarovým a softwarovým kombinacím, získáte hlubší přehled o tom, jak se vývoj aplikací liší na jednotlivých platformách. Tento přehled vám pomůže nejen rozumět technologickým rozdílům, ale i se lépe orientovat ve správných nástrojích pro správný typ aplikace. Pro začátečníky může být ideálním startem Raspberry Pi 400 s Ubuntu 64-bit, což je skvélé pro seznámení se s C# a .NET vývojem. Další podrobnosti o vývoji na Raspberry Pi lze nalézt v článku na GitHubu.

Když už mluvíme o multiplatformním nasazení aplikací, volba vývojového prostředí a operačního systému neomezuje místo, kam váš kód bude nasazen. .NET 7 podporuje různé platformy pro nasazení, včetně Windows 10 (verze 1607 a novější), macOS (Catalina a novější), Linux (např. Ubuntu 18.04 a novější), Android (API 21 a novější), iOS (10 a novější). Důležitým bodem je, že podpora Windows ARM64 byla přidána již v .NET 5 a můžete vyvíjet i nasazovat aplikace na ARM zařízení jako Microsoft Surface Pro X. Vývoj na Apple M1 Macu s Windows 11 ARM virtuální strojem je dokonce dvakrát rychlejší.

Pokud si chcete vybrat nástroj pro vývoj, je dobré se zaměřit na Visual Studio 2022 pro Windows, které je široce používáno v profesní komunitě Microsoft vývojářů. I když se rozhodnete pro Visual Studio Code pro vaše vývojové úkoly, je dobré se seznámit i s Visual Studio 2022, jelikož pro některé úkoly, jako například testování webových a datových služeb, je Visual Studio Code neocenitelným nástrojem díky rozšíření, jako je REST Client.

Pro instalaci Visual Studio 2022 pro Windows budete potřebovat stáhnout a nainstalovat správnou verzi, vybrat potřebné pracovní zátěže jako ASP.NET, vývoj pro Azure, .NET MAUI a desktopový vývoj. Pokud ještě nemáte Visual Studio 2022, je k dispozici zdarma pro studenty a otevřené zdrojové přispěvatele v edici Community. Po instalaci Visual Studio budete vyzváni k přihlášení pomocí Microsoft účtu a konfiguraci prostředí pro C#. Pokud chcete upravit klávesové zkratky pro vaše potřeby, můžete to provést v nastaveních prostředí.

Visual Studio Code, které je vysoce populární díky své flexibilitě, se často používá pro webový vývoj a testování. Ačkoliv je dostupná edice Insider pro ty, kteří chtějí mít přístup k denním buildům, pro většinu vývojářů je dostatečná stabilní verze. Při instalaci Visual Studio Code je nezbytné mít nainstalovány také .NET SDK (verze 6.0 a 7.0) a C# extension, aby bylo možné efektivně pracovat na .NET aplikacích. Visual Studio Code nabízí rozsáhlou podporu pro rozšíření, která vám umožní vylepšit vývojový proces.

Pro práci s .NET aplikacemi je klíčové nejen správně nastavit vývojové prostředí, ale také chápat rozdíly mezi jednotlivými platformami a nástroji. Je důležité si být vědom různých možností nasazení a podpory multiplatformních vývojových nástrojů, což vám umožní efektivně přecházet mezi různými operačními systémy a zařízeními.

Jak správně používat různé strategie mapování v EF Core při práci s relačními databázemi

Využívání různých strategií mapování, jako jsou TPH, TPT a TPC, je v EF Core klíčovým nástrojem pro efektivní práci s dědičností v relačních databázích. Každá z těchto strategií poskytuje jiný způsob, jak spravovat vztahy mezi třídami a databázovými tabulkami, což má přímý vliv na výkon, strukturu databáze a flexibilitu aplikace. V následujícím textu se podíváme na praktické příklady těchto strategií a způsob jejich implementace.

Pokud začneme s jednoduchou aplikací, která používá model "People" a ukládá různé typy osob, jako jsou studenti a zaměstnanci, první krok je vytvoření tabulky "People". Tento model lze použít ve třech různých mapovacích strategiích, které ovlivní způsob, jakým jsou data uložena a jak jsou propojeny různé objekty v aplikaci.

Při použití TPH (Table per Hierarchy) bude celá dědičnost reprezentována jednou tabulkou, která obsahuje všechny sloupce pro všechny možné typy v hierarchii. Příklad v kódu ukazuje, jak se při zavedení této strategie vytvoří tabulka s jedním sloupcem pro každou třídu v hierarchii. Tento přístup může být výhodný pro jednoduchost, ale přináší některé problémy s výkonem, pokud tabulka obsahuje velké množství záznamů nebo různých typů dat.

Pokud zvolíme TPT (Table per Type), každá třída v hierarchii bude mít svou vlastní tabulku, která bude mít cizí klíč na rodičovskou tabulku. Tato strategie pomáhá eliminovat některé nevýhody TPH, protože každá tabulka obsahuje pouze specifické sloupce pro daný typ. Nicméně, tento přístup může vést k více JOIN operacím při dotazech, což může mít negativní vliv na výkon.

Pro ještě podrobnější řízení dědičnosti se používá TPC (Table per Concrete Class). Tato strategie vytvoří samostatnou tabulku pro každý konkrétní typ, což znamená, že každý záznam bude mít svou vlastní tabulku, která neobsahuje žádné dědičné sloupce. Tento přístup může zjednodušit strukturu databáze, ale na druhou stranu může vést k duplikování dat v tabulkách, což může být neefektivní z hlediska údržby a výkonu.

Po nastavení správné strategie mapování je nutné věnovat pozornost také způsobu generování ID hodnot. Například při použití TPC je vhodné implementovat sekvenci pro generování unikátních ID pro každou tabulku, což je řešeno prostřednictvím SQL sekvence, jak ukazuje příklad kódu. Tento přístup zajišťuje, že hodnoty ID nebudou kolidovat mezi tabulkami, a zároveň umožňuje jejich flexibilní generování podle definovaných pravidel.

Důležité je, že přechod mezi těmito strategiemi může mít vliv na výkon aplikace. TPH může být rychlejší pro jednoduché aplikace s nízkým objemem dat, ale může mít problémy s výkonem u složitějších scénářů. Naopak TPT a TPC mohou být náročnější na dotazy a správu, ale přinášejí vyšší úroveň normalizace a lepší kontrolu nad strukturou databáze.

Také je třeba vzít v úvahu, že každá strategie může být vhodná pro jiné scénáře. TPH je ideální pro případy, kdy máme několik typů, které sdílejí většinu svých vlastností. TPT je vhodnější, když jsou rozdíly mezi typy značné, ale nechceme je ukládat do jedné tabulky. TPC se používá, když chceme mít co největší kontrolu nad jednotlivými entitami a minimalizovat nadbytečné sloupce v databázi.

Při práci s databázemi v reálných aplikacích je také důležité mít na paměti otázku zálohování a správy databázových schémat. Každá změna v konfiguraci mapování by měla být pečlivě testována a migrována do produkčního prostředí, aby nedošlo k nechtěným problémům s integritou dat.

Jak implementovat a spravovat data v SQL Serveru pomocí Entity Frameworku a EF Core 7

Při práci s databázemi a jejich integrací do aplikací, zejména v prostředí SQL Serveru, se stále častěji používá ORM nástroj jako Entity Framework (EF). Tento nástroj umožňuje snadnou manipulaci s databázemi, generování modelů a provádění dotazů bez nutnosti psát složité SQL dotazy. EF Core 7 přináší nové možnosti, jako je podpora pro výpočetní vlastnosti a rozšíření pro sledování změn u entit.

V tomto článku se zaměříme na implementaci základních kroků, které vám umožní generovat a spravovat entity pomocí EF Core 7, a to na příkladu aplikace pro správu dat o zaměstnancích v databázi Northwind. Kromě toho si ukážeme, jak přidat vlastnosti, které se počítají automaticky při vytvoření entity, což přináší větší flexibilitu a efektivitu při práci s daty.

Prvním krokem v práci s databází SQL Server je vytvoření modelů entit na základě existující databáze. Pokud máme databázi, jako je například Northwind, můžeme pomocí nástroje dotnet-ef vygenerovat třídy, které budou reprezentovat tabulky v databázi. Použijeme následující příkaz:

bash
dotnet ef dbcontext scaffold "Data Source=.;Initial Catalog=Northwind;Integrated Security=true;TrustServerCertificate=True;" Microsoft.EntityFrameworkCore.SqlServer --namespace Packt.Shared --data-annotations

Tento příkaz vygeneruje třídy pro všechny tabulky v databázi, které následně můžeme použít v naší aplikaci. Pokud například chceme, aby sloupec CustomerId měl specifické omezení na velikost a formát, můžeme použít datové anotace, jako je ukázáno níže:

csharp
[Key] [StringLength(5)] [RegularExpression("[A-Z]{5}")]
public string CustomerId { get; set; } = null!;

Tento kód zajišťuje, že hodnota CustomerId bude obsahovat pouze pět velkých písmen, čímž se zaručí konzistence dat v naší aplikaci.

Dalším důležitým krokem je přesunutí generovaných tříd do samostatné knihovny tříd, což usnadní správu datového kontextu. Tento krok zahrnuje vytvoření nové třídy pro připojení k databázi a přidání příslušných služeb do aplikace. Takto vytvořený kontext je možné používat v aplikaci jako závislost (dependency injection), což umožňuje snadné testování a údržbu kódu.

csharp
public static class NorthwindContextExtensions
{ public static IServiceCollection AddNorthwindContext( this IServiceCollection services, string connectionString = "Data Source=.;Initial Catalog=Northwind;Integrated Security=true;MultipleActiveResultsets=true;Encrypt=false") { services.AddDbContext<NorthwindContext>(options => { options.UseSqlServer(connectionString); options.LogTo(Console.WriteLine, new[] { Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId.CommandExecuting }); }); return services; } }

Tento kód přidává metodu pro registraci kontextu NorthwindContext do kolekce služeb v aplikaci, což znamená, že bude automaticky dostupný pro všechny komponenty, které ho potřebují.

Dále se podíváme na novou funkcionalitu, kterou EF Core 7 přináší v podobě rozhraní IMaterializationInterceptor. Toto rozhraní umožňuje připojit logiku, která bude prováděna před a po vytvoření entity, což je ideální pro výpočetní vlastnosti. Příklad: Pokud máme potřebu udržovat informaci o čase, kdy byla entita naposledy aktualizována, můžeme tuto hodnotu automaticky nastavit při vytváření nebo změně entity.

Nejprve vytvoříme rozhraní, které přidá vlastnost LastRefreshed, jež bude uchovávat čas poslední aktualizace entity:

csharp
public interface IHasLastRefreshed
{ DateTimeOffset LastRefreshed { get; set; } }

Poté implementujeme toto rozhraní v entitě Employee:

csharp
public partial class Employee : IHasLastRefreshed { [NotMapped] public DateTimeOffset LastRefreshed { get; set; } }

Následně definujeme interceptor, který bude tento čas automaticky nastavovat při inicializaci entity:

csharp
public class SetLastRefreshedInterceptor : IMaterializationInterceptor
{ public object InitializedInstance(MaterializationInterceptionData materializationData, object entity) { if (entity is IHasLastRefreshed entityWithLastRefreshed) { entityWithLastRefreshed.LastRefreshed = DateTimeOffset.UtcNow; } return entity; } }

Tento interceptor bude zajišťovat, že každý objekt, který implementuje IHasLastRefreshed, bude automaticky dostávat aktuální čas při jeho inicializaci. Nakonec musíme tento interceptor zaregistrovat v kontextu databáze:

csharp
public partial class NorthwindContext : DbContext
{ private static readonly SetLastRefreshedInterceptor setLastRefreshedInterceptor = new();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured) { optionsBuilder.UseSqlServer("..."); } } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.AddInterceptors(setLastRefreshedInterceptor); } }

Tento krok zajistí, že každá entita, která implementuje rozhraní IHasLastRefreshed, bude mít při každém načtení z databáze automaticky nastaven čas poslední aktualizace.

Pokud jde o další aspekt správy databázového kontextu, je důležité si uvědomit, že správná organizace kódu, například rozdělení na různé projekty pro různé oblasti aplikace (např. modely entit, kontexty, služby), je klíčem k udržitelnosti a snadné údržbě aplikace. Také by měla být zajištěna správná konfigurace připojení k databázi a možnost jeho snadného přizpůsobení, například pro různé prostředí.

Jak správně pracovat s OData modely a službami v aplikacích

Při práci s OData v .NET aplikacích se často setkáváme s potřebou správně definovat a spravovat různé modely, které jsou následně exponovány prostřednictvím webových služeb. Tento proces zahrnuje několik klíčových kroků, od definice samotného modelu, přes nastavení dotazovacích možností až po testování a správu OData kontrolerů.

Nejdůležitějšími částmi při vytváření OData služeb jsou bezpochyby správné nastavení OData modelů a zajištění toho, aby odpovídaly požadavkům aplikace. OData modely slouží k definici struktury dat a vztahů mezi entitami, které budou zpřístupněny prostřednictvím webového rozhraní.

Po definici modelu je nutné nastavit různé dotazovací možnosti, které umožní klientům přistupovat k datům s využitím filtrů, třídění a dalších parametrů. To zahrnuje povolení operací jako $select (výběr polí), $expand (rozšíření vztahů mezi entitami), $filter (filtrace), $orderby (třídění), $top (omezení počtu záznamů) a $count (počet záznamů). Tyto možnosti usnadňují správu dat a umožňují efektivní práci s velkými objemy informací.

Dále je potřeba definovat kontrolery, které budou sloužit k získávání a manipulaci s daty z databáze. OData kontrolery dědí z třídy ODataController, což poskytuje potřebnou funkcionalitu pro zpracování požadavků typu GET. Pomocí konstruktorové injekce lze do těchto kontrolerů vkládat kontext databáze, což umožní přístup k entitám, jako jsou kategorie, produkty nebo dodavatelé.

Pro ilustraci si vezměme příklad kontroleru pro kategorie. Tento kontroler obsahuje dvě metody: jednu pro získání všech kategorií a druhou pro získání kategorie podle jejího jedinečného identifikátoru. Je zde také použito atributu [EnableQuery], který umožňuje použití dotazovacích parametrů přímo v URL.

csharp
[EnableQuery] public IActionResult Get() { return Ok(db.Categories); } [EnableQuery] public IActionResult Get(int key) { return Ok(db.Categories.Where(category => category.CategoryId == key)); }

Tento přístup zajišťuje flexibilitu a umožňuje uživatelům efektivně dotazovat data na základě jejich potřeb. Zajímavým krokem je také logování SQL dotazů prováděných Entity Framework Core, které ukazuje, jak jsou dotazy na OData automaticky přeloženy do efektivních SQL dotazů bez potřeby načítat veškerá data do služby a následně je filtrovat.

Po vytvoření kontrolerů a zajištění správného fungování služeb je důležité testovat funkčnost OData modelů. K tomu je ideální použít nástroje jako Swagger, který automaticky generuje dokumentaci pro OData služby a umožňuje snadno testovat různé koncové body (endpointy). Testování pomocí Swaggeru je intuitivní a poskytuje přehled o tom, jak modely a kontrolery reagují na různé požadavky. Můžeme například testovat dotazy typu GET /catalog/Categories, které vrátí seznam všech kategorií.

Alternativně lze použít Visual Studio Code s rozšířením REST Client, které poskytuje další možnost testování OData služeb pomocí jednoduchých HTTP požadavků. Tento nástroj je rychlý a efektivní pro testování jednotlivých koncových bodů bez potřeby používat složitější rozhraní jako Swagger.

Je důležité mít na paměti, že OData nabízí širokou škálu funkcí, které umožňují efektivní práci s daty. Mezi tyto funkce patří možnost specifikovat sloupce, které mají být vráceny, aplikovat filtry na data přímo na straně serveru a omezit množství vrácených dat pomocí parametrů jako $top nebo $filter. Tento přístup pomáhá udržet aplikace efektivní a minimalizovat zátěž na server.

V praxi je také důležité zajišťovat správnou autentizaci a autorizaci pro přístup k těmto OData službám. Zabezpečení je klíčové pro ochranu citlivých dat a zajištění správného přístupu uživatelů.

Pokud jde o přístup k OData službám z klientské aplikace, je nezbytné správně nakonfigurovat všechny parametry pro práci s daty. Tento proces zahrnuje nejen správné nastavení kontrolerů a modelů, ale i zajištění odpovídající úpravy aplikace pro interakci s těmito službami. Mnoho knihoven a nástrojů dnes nabízí možnosti pro efektivní komunikaci s OData službami, ať už jde o klienty pro webové aplikace nebo mobilní zařízení.

Jak přidat podporu pro EF Core do databáze Northwind s GraphQL

Pro přidání podpory pro EF Core v databázi Northwind, když pracujeme s GraphQL, je nutné provést několik kroků, které umožní integraci databázového kontextu EF Core do GraphQL dotazů pomocí nástroje Hot Chocolate. Tento proces není složitý, ale vyžaduje správné nastavení a pochopení základních principů práce s GraphQL a EF Core.

Prvním krokem je přidání potřebného balíčku, který zajistí bezproblémovou integraci s EF Core. Tento balíček umožní automatické provázání databázového kontextu s GraphQL dotazy. Zde je důležité dbát na to, aby všechny balíčky Hot Chocolate měly stejnou verzi, což zajistí jejich vzájemnou kompatibilitu. Po přidání tohoto balíčku je nutné provést referenci na projekt obsahující databázový kontext, což je v tomto případě projekt, který obsahuje modely a kontext pro databázi Northwind.

Další nezbytný krok spočívá ve vybudování celého projektu pomocí příkazu dotnet build v terminálu nebo příkazové řádce. Pokud se odkazujete na projekt mimo aktuální řešení, je třeba ho nejprve postavit, než bude možné použít běžnou funkci kompilace v aplikaci Visual Studio 2022. Tento krok je důležitý pro správnou inicializaci a zavedení všech potřebných závislostí.

V souboru Program.cs je třeba naimportovat správný namespace, který umožní práci s modelem EF Core pro databázi Northwind. Následně se do kódu přidá registrace kontextu Northwind a podpora pro GraphQL. Tento krok je klíčový pro zajištění správného fungování služby a její interakce s databází.

Pro nastavení GraphQL dotazů je důležité správně definovat grafy objektů v souboru Query.cs. V tomto souboru se přidávají metody, které budou vracet požadovaná data, například seznam kategorií, jednotlivé kategorie, produkty kategorie nebo všechny produkty. Důležité je také správně nakonfigurovat vztahy mezi objekty, jako je například zahrnutí produktů kategorie nebo kategorií pro produkty.

Po těchto krocích je možné začít psát samotné GraphQL dotazy. Pro testování je doporučeno spustit službu Northwind.GraphQL a použít nástroj Banana Cake Pop pro interaktivní tvorbu a vykonávání dotazů. Tento nástroj umožňuje snadné ověření definic schémat a vykonávání dotazů na různé entity databáze, jako jsou kategorie a produkty.

Pro pokročilé použití GraphQL je možné psát dotazy, které kombinují více vrstev dat. Například je možné získat seznam všech kategorií včetně jejich ID, názvu a popisu, nebo provádět dotazy na produkty podle kategorií. U každého dotazu je možné specifikovat požadované sloupce a pole, jako je název produktu, cena nebo množství na skladě. Pomocí GraphQL lze snadno sestavovat složitější dotazy a získávat tak podrobnější a relevantní data.

Při práci s GraphQL je také užitečné používat proměnné, které umožňují flexibilně měnit hodnoty parametrů, jako je ID kategorie. To umožňuje dynamické vykonávání dotazů na různé kategorie nebo produkty bez nutnosti měnit samotný kód dotazu.

Pokud jde o výstupy, GraphQL poskytuje data v dobře strukturované podobě, což zjednodušuje jejich následnou manipulaci. Výstup je často formátován jako JSON, což je ideální pro použití v moderních webových aplikacích a API.

Kromě toho, že je důležité chápat základní kroky nastavení a vytváření dotazů, je nezbytné mít na paměti několik klíčových aspektů pro efektivní práci s GraphQL a EF Core. Zaprvé, správná optimalizace dotazů je klíčová, protože některé dotazy mohou generovat velký objem dat, což může ovlivnit výkon aplikace. Je také nutné správně spravovat vztahy mezi entitami, zejména pokud jde o zahrnutí souvisejících dat, jako jsou produkty kategorie nebo kategorie produktu.

Pochopení toho, jak GraphQL integruje a pracuje s databázovými modely, pomůže nejen optimalizovat dotazy, ale i snížit složitost celkového architektonického návrhu aplikace. Při psaní a ladění dotazů je důležité mít na paměti, že každý dotaz může mít svůj vlastní optimální způsob strukturování a vykonávání.