Řešení SerializationException v nástrojích Entity Framework 6

Visual Studio Web Development

5 years ago

Code-first migrace v Entity Frameworku 6 jsou skvělým nástrojem pro práci, ale ve chvíli kdy vás zasáhnou chybovou hláškou, často to je těžko vysvětlitelným způsobem. Jedním z nich je SerializationException při pokusu o provedení jakýchkoliv EF příkazů. V tomto článku nastíním řešení, které jsme objevili.

Problém

Po delší době úspěšného používání migrací v našem projektu náhle přestaly spolupracovat. Všechny pokusy o spuštění EF příkazů jak z PowerShellu tak přímo nástrojem migrate.exe skončily následující chybovou hláškou:

System.Runtime.Serialization.SerializationException: Type is not resolved for member 'System.Data.Entity.Migrations.Design.ToolingFacade+GetContextTypeRunner,EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate) at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner) at System.Data.Entity.Migrations.Design.ToolingFacade.GetContextType(String contextTypeName) at System.Data.Entity.Migrations.EnableMigrationsCommand.FindContextToEnable(String contextTypeName) at System.Data.Entity.Migrations.EnableMigrationsCommand.<>c__DisplayClass2.<.ctor>b__0() at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command) Type is not resolved for member 'System.Data.Entity.Migrations.Design.ToolingFacade+GetContextTypeRunner,EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.

Je zřejmé, že popis této výjimky nám příliš užitečných informací pro vyřešení problému nedává, takže jsme se přirozeně obrátili na StackOverflow.

Řešení

Neplatná cesta

Většina odpovědí na SO vyřešila tento problém ověřením cesty k projektu na pevném disku. Nejčastějším zdrojem problémů byl znak & v názvu jedné ze složek. Tyto znaky EF zřejmě nedokáže zpracovat. Bohužel, v našem případě byla cesta k projektu poměrně jednoduchá a neobsahovala žádné neobvyklé znaky, dokonce ani mezeru.

Binding redirect

Po téměř celém dni pátrání které zahrnovalo přeinstalaci všech NuGet balíčků a upgrade knihovny na .NET Standard jsem náhodou narazil na příčinu - neplatný binding redirect. Náš App.config obsahoval následující:

<dependentAssembly>
   <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
   <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.2.0.0" />
   <codeBase version="6.0.0.0" href="libs/EntityFramework.dll" />
</dependentAssembly>

Tento redirect na první pohled vypadá v pořádku a verze NuGet balíčku, kterou používáme je skutečně 6.2. Avšak, když jsem spustil následující PowerShell příkaz proti EntityFramework.dll:

([system.reflection.assembly]::LoadFile("C:\Users\Martin\.nuget\packages\entityframework\6.2.0\lib\net45\entityframework.dll")).FullName

Dostalo se mi úplně jiného výsledku:

EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Ukazuje se, že plné jméno assembly je stále jednoduše 6.0.0.0 a pouze FileVersion odpovídá verzi NuGet balíčku. Změnil jsem newVersion atribut na 6.0.0.0 a voilá - příkazy EF znovu běží bez potíží!

<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />

Shrnutí

Řešení nepopisných výjimek z nástrojů EF může být náročné, ale nakonec nás obvykle naučí něco nového. V tomto případě ponaučení, že problém je někdy tam, kde jej nejméně očekáváme.