EF Core 6 a zákeřný Column Order
Tento článek byl napsán v roce 2021. Vývojářské technologie se neustále inovují a článek již nemusí popisovat aktuální stav technologie, ideální řešení a můj současný pohled na dané téma.
Jedno z nepatrných vylepšení EF Core 6 spočívá v možnosti nastavit si pořadí sloupečků v databázi pomocí atributu Column. Můžeme mít properties v rámci třídy v jednom pořadí a v databázi v pořadí jiném. Doposud jsem to nepoužíval ani ve fluent api, ale teď jsem zjistil, že to má zajímavé chování.
Jak to funguje
Za normálních okolností je dáno pořadí sloupečků v DB pořadím properties v rámci třídy. Takže pro:
public class Webinar { public int Id { get; set; } [Unicode] public string Title { get; set; } [Precision(14,2)] public decimal Price { get; set; } public DateTime PublicFrom { get; set; } }
je pořadí: Id, Title, Price, PublicFrom. To asi nepřekvapí.
Zběhlý vývojář také ví, že EF Core upřednostní klíč. Takže když pořadí properties otočíme takto:
public class Webinar { [Unicode] public string Title { get; set; } public int Id { get; set; } [Precision(14,2)] public decimal Price { get; set; } public DateTime PublicFrom { get; set; } }
výsledek bude úplně stejný a pořadí sloupečků bude opět: Id, Title, Price, PublicFrom. To je asi dobře, protože klíč chceme vidět jako první sloupec.
Column(Order)
Od EF Core 6 máme k dispozici novou vlastnost Order, kterou najdeme u atributu Column. Takže pořadím můžeme zamávat. Podívejte se na další příklad a zkuste odhadnout pořadí sloupečků v databázi:
public class Webinar { [Unicode] public string Title { get; set; } [Precision(14,2)] public decimal Price { get; set; } public int Id { get; set; } [Column(Order = 2)] public DateTime PublicFrom { get; set; } }
Máme tedy Id, který EF Core rád upřednostňuje a zároveň PublicFrom, který označujeme atributem Column(Order=2)). Výsledek může překvapit:
CREATE TABLE [Webinars] ( [PublicFrom] datetime2 NOT NULL, [Id] int NOT NULL IDENTITY, [Title] nvarchar(max) NULL, [Price] decimal(14,2) NOT NULL, [DateFrom] datetime2 NOT NULL CONSTRAINT [PK_Webinars] PRIMARY KEY ([Id]) );
Pořadí je tedy: PublicFrom, Id, Title, Price. Tedy pravidla jsou taková, že:
- pokud je property označena s [Column(Order)], dostává výsostní přednost bez ohledu na číslo v Order
- dále má přednost vždy property, která je klíč
- nakonec jdou ostatní properties s pořadím deklarovaným ve třídě
Použití v praxi
Pokud chci pořadí řešit a v třídě někde použiju [Column(Order)], pak si rovnou nastavím vždy pořadí i pro klíč, abych ho měl hned na začátku. Prioritu nastavím jen u sloupců, které chci skutečně vidět první. Zbytek neřeším.