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.