\

Školení Návrhové vzory, OOP a UML


 Friday, 24 February 2012
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.Smile

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.

 

EFTables

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, 24 February 2012 22:06:21 (Central Europe Standard Time, UTC+01:00)       
Comments [4]  .NET Framework | C# | Entity Framework | LINQ