Entity Framework 4.3. Code First - (nechutný) problém s TPC mapováním?
Update 25. 2.2011: Tak chyba potvrzena EF týmem. Jedná se skutečně o chybu, která je částečně popsána v known issues.
Diego B Vega : @Rene Stein: Thanks for reporting this and for the repro. What you describe seems to be a bug in TPC mapping that we are already aware of and that we are planning to fix in the upcoming EF 4.3.1. Please take a look at the list of known issues above for more information.
Jedná se tedy o chybu, kterou někdo zmínil i v komentářích. Zarážející ale je, že k chybě “chybí sloupec v databázi” se dostanete teprve tehdy, kdy vygenerujete databázi s jiným než požadovaným schématem, odchytnete výjimku při dotazování a podíváte se na popisek vnořené výjimky. V “known issues” EF by spíš podle mě mělo být - ve verzi 4.3 se vám ani nepodaří vygenerovat databázi s TPC mapováním dědičnosti a volání metody MapInheritedProperties při konfiguraci entit je jen zbytečná dekorace v kódu a cvičení v marnosti.
Mohl by prosím někdo ověřit, že jsem buď udělal nějakou triviální chybu při mapování, anebo potvrdit mé podezření, že je EF Code First v poslední verzi 4.3 natolik prolezlý chybami, že v něm nefunguje ani tento triviální scénář.
Problém se snažím reprodukovat na tomto kódu.
Mám třídy Base a Derived. Jejich role asi vysvětlovat nikomu nemusím.
Snažím se pro mapování třídy Derived do databáze použít v db kontextu strategii TPC – table per (concrete) class (metoda MapInheritedProperties).
Po spuštění se aplikace vytvoří databáze se dvěma tabulkami. Struktura databáze ale odpovídá TPT strategii pro mapování dědičnosti:
Tabulka Base má sloupce Id a BaseProperty, tabulka Derived Id a Note. Volání MapInheritedProperties je tedy zcela ignorováno.
Jak popisuju i v kódu, matoucí je to, že Entity Framework sice mapuje třídy do databáze podle TPT strategie, ale dotazy klade, jako kdyby v databázi byly třída Derived namapována TPC strategií.
Vygenerovaný SQL dotaz do tabulky Derived vypadá takto:
SELECT '0X0X' AS [C1], [Extent1].[id] AS [id], [Extent1].[BaseProperty] AS [BaseProperty], [Extent1].[Note] AS [Note] FROM [dbo].[Derived] AS [Extent1] Schizofrenní Entity Framework se beze všech skrupulí snaží dohledat v tabulce Derived sloupec BaseProperty (TPC mapování), což pochopitelně skončí výjimkou při vykonávání dotazu, protože se jiná část jeho vícečetné osobnosti složené z nespolupracujících spoluautorů EF rozhodla při generování databáze, že TPT je pro každého aplikačního vývojáře vždycky jasná volba.
A protože perverzních projevů EF se při pátečním večeru nelze nabažit, tak tady je skript pro založení databáze, který jsem vytáhl z podkladového ObjectContextu a který by měl mapovat podle TPC, což se ale nestane, protože je proti databázi spuštěn skript zcela jiný.
Výsledek Trace.WriteLine(((IObjectContextAdapter) context).ObjectContext.CreateDatabaseScript());
Projekt s reprodukcí problému ke stažení.
Friday, February 24, 2012 10:06:21 PM (Central Europe Standard Time, UTC+01:00)
.NET Framework | C# | Entity Framework | LINQ