efcore icon indicating copy to clipboard operation
efcore copied to clipboard

Scaffolding doesn't work with the latest version of Mono.TextTemplating

Open testirme opened this issue 2 years ago • 26 comments
trafficstars

When I updated all versions to 8, T4 started giving the following error.

error : The type 'Microsoft.EntityFrameworkCore.Metadata.IModel' of the parameter 'Model' did not match the type passed to the template

error : The host parameter 'Model' could not be converted to the type 'System.CodeDom.CodeTypeReference' specified in the template

error : Error running transform: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.BadImageFormatException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Reference assemblies cannot be loaded for execution. (0x80131058)
File name: 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.BadImageFormatException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL'. Reference assemblies cannot be loaded for execution. (0x80131058)
File name: 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL' ---> System.BadImageFormatException: Cannot load a reference assembly for execution.
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
   at Mono.TextTemplating.TemplateAssemblyLoadContext.Load(AssemblyName assemblyName) in /_/Mono.TextTemplating/Mono.TextTemplating/TemplateAssemblyLoadContext.cs:line 64
   at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingLoad(AssemblyName assemblyName)
   at System.Runtime.Loader.AssemblyLoadContext.Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
   at Microsoft.VisualStudio.TextTemplating3837c1b.GeneratedTextTransformation.TransformText()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at Mono.TextTemplating.CompiledTemplate.TemplateProcessor.CreateAndProcess(ITextTemplatingEngineHost host, CompiledAssemblyData templateAssemblyData, String templateAssemblyFile, String fullName, CultureInfo culture, String[] referencedAssemblyFiles) in /_/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.TemplateExecutor.cs:line 78

Processing 'D:\AKINSOFT\cloud\erpcloud\Libraries\Asnet.Cloud.Data\CodeTemplates\EFCore\DbContext.t4' failed.

testirme avatar Nov 22 '23 06:11 testirme

Same here. I updated all the related ef packages, i updated my t4 templates based on Microsoft.EntityFrameworkCore.Templates . But the problem is same. If i remove t4 templates, scaffold is generated correctly.

I am using postgresql.

risperdal avatar Nov 22 '23 06:11 risperdal

@risperdal Please post your csproj file.

ajcvickers avatar Nov 22 '23 12:11 ajcvickers

@risperdal Please post your csproj file.

hello, I have the same problem. the content of my csproj file is as follows. I would be grateful if you can help what we need to do.

Asnet.Cloud.Data.csproj.zip

akinsoftyazilim42 avatar Nov 23 '23 07:11 akinsoftyazilim42

@akinsoftyazilim42 You are not using the version 8 packages:

    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.9">
    </PackageReference>
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" />
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.Design" Version="1.1.0" />

ErikEJ avatar Nov 23 '23 07:11 ErikEJ

I'm very sorry. I had taken it back. Now I'm sending you the problematic version. Asnet.Cloud.Data.csproj.zip

akinsoftyazilim42 avatar Nov 23 '23 07:11 akinsoftyazilim42

@akinsoftyazilim42 Remove Npgsql.EntityFrameworkCore.PostgreSQL.Design. It's an obsolete package.

ajcvickers avatar Nov 23 '23 09:11 ajcvickers

@akinsoftyazilim42 Remove Npgsql.EntityFrameworkCore.PostgreSQL.Design. It's an obsolete package.

We uninstalled the Npgsql.EntityFrameworkCore.PostgreSQL.Design package, but the error still persists.

testirme avatar Nov 23 '23 10:11 testirme

@akinsoftyazilim42 Remove Npgsql.EntityFrameworkCore.PostgreSQL.Design. It's an obsolete package.

yes. i tried it and now i get the same error.

akinsoftyazilim42 avatar Nov 23 '23 12:11 akinsoftyazilim42

Same error here, without using any PostgreSQL libraries. Used the Upgrade-function of Visual Studio to update my .NET 7 project to .NET 8. Found out that now SQL Date objects are mapped to DateOnly, wanted to change this using a T4 template as shown here, but I get these errors when trying to scaffold my existing DB tables:

error : The type 'Microsoft.EntityFrameworkCore.Metadata.IModel' of the parameter 'Model' did not match the type passed to the template

error : The host parameter 'Model' could not be converted to the type 'System.CodeDom.CodeTypeReference' specified in the template
error : Error running transform: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.MissingMethodException: Method not found: 'System.String Microsoft.EntityFrameworkCore.ScaffoldingModelExtensions.GetDbSetName(Microsoft.EntityFrameworkCore.Metadata.IReadOnlyEntityType)'.
   at Microsoft.VisualStudio.TextTemplating752bc159.GeneratedTextTransformation.TransformText()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at Mono.TextTemplating.CompiledTemplate.TemplateProcessor.CreateAndProcess(ITextTemplatingEngineHost host, CompiledAssemblyData templateAssemblyData, String templateAssemblyFile, String fullName, CultureInfo culture, String[] referencedAssemblyFiles) in /_/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.TemplateExecutor.cs:line 78

Attached is my .csproj-file: Projectfile.zip

Stroomtang avatar Nov 23 '23 17:11 Stroomtang

Have you tried with a clean set of the latest t4 templates?

ErikEJ avatar Nov 23 '23 20:11 ErikEJ

Have you tried with a clean set of the latest t4 templates?

I did, I didn't use templates before (didn't need it) so they are the latest. The DbContext.t4 starts (after the imports) with

if (!ProductInfo.GetVersion().StartsWith("8.0"))

Stroomtang avatar Nov 23 '23 21:11 Stroomtang

The cause of the error is "Microsoft.VisualStudio.Web.CodeGeneration.Design"

t4

testirme avatar Nov 24 '23 08:11 testirme

Thanks for info. ;)

akinsoftyazilim42 avatar Nov 24 '23 08:11 akinsoftyazilim42

Thanks for info. ;)

you are welcome

testirme avatar Nov 24 '23 08:11 testirme

Thanks for the information, but it didn't work for me.

mehmetbicer avatar Nov 24 '23 08:11 mehmetbicer

@bricelam Can you take a look at this?

ajcvickers avatar Nov 24 '23 09:11 ajcvickers

Removing the reference to Microsoft.VisualStudio.Web.CodeGeneration.Design fixed it for me.

Stroomtang avatar Nov 24 '23 10:11 Stroomtang

Note for triage: I suspect the issue here is that VS package is bringing Mono.TextTemplating 2.3.1, but EF seems to require 2.2.1.

ajcvickers avatar Nov 27 '23 12:11 ajcvickers

Notes for triage:

The underlying issue here is that Mono.TextTemplating 2.2.1 loads the assembly into the default load context, which allows it to use types created by the EF tooling inside the template. An intentional change was made to stop loading the assembly in this way, which, as far as I can tell, makes it incompatible with EF Core's use. This is presumably why we didn't update to the new version. Assigning the types directly generates:

System.InvalidCastException: [A]Microsoft.EntityFrameworkCore.Metadata.Internal.Model cannot be cast to [B]Microsoft.EntityFrameworkCore.Metadata.Internal.Model. Type A originates from 'Microsoft.EntityFrameworkCore, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60' in the context 'Default' at location 'C:\local\code\efcore\artifacts\bin\EFCore.Design.Tests\Debug\net8.0\Microsoft.EntityFrameworkCore.dll'. Type B originates from 'Microsoft.EntityFrameworkCore, Version=42.42.42.42, Culture=neutral, PublicKeyToken=adb9793829ddae60' in the context '"" Mono.TextTemplating.TemplateAssemblyLoadContext #1' at location 'C:\local\code\efcore\artifacts\bin\EFCore.Design.Tests\Debug\net8.0\Microsoft.EntityFrameworkCore.dll'.
   at Microsoft.VisualStudio.TextTemplating827e0a4.GeneratedTextTransformation.Initialize()
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
   at Mono.TextTemplating.CompiledTemplate.TemplateProcessor.CreateAndProcess(ITextTemplatingEngineHost host, CompiledAssemblyData templateAssemblyData, String templateAssemblyFile, String fullName, CultureInfo culture, String[] referencedAssemblyFiles) in /_/Mono.TextTemplating/Mono.TextTemplating/CompiledTemplate.TemplateExecutor.cs:line 77

I verified using Reflection calls that loading the assembly as before fixes the issues seen with 2.3.1. See #32495.

We should check with @mhutch that there isn't some simple fix. Beyond that, I think we have a few options here, but none seem great:

  • Tell users to pin their Mono.TextTemplating package to 2.2.1 when using EF
  • Do something hacky like in the draft PR
  • Fork the Mono.TextTemplating and stop taking a dependency on the external package

ajcvickers avatar Dec 02 '23 16:12 ajcvickers

I've added an option to Mono.TextTemplating to allow the host to disable the use of AssemblyLoadContext and revert to the old (current) AppDomain behavior.

I have also made some changes to the loading behavior when using AssemblyLoadContext that may fix the underlying issue and make disabling it unnecessary.

If these solve the issue, I can backport to 2.3.x and make a new release.

mhutch avatar Jan 10 '24 23:01 mhutch

@mhutch I tried first with the latest preview package, and that still failed. But then I built packages locally from your main branch and used those, and all the tests pass even without setting DisableAssemblyLoadContext.

Sorry for being slow to test this, and thanks for the quick fix! As soon as a preview package is available, we can update our main branch, which will allow customers to test with our daily build.

ajcvickers avatar Jan 22 '24 18:01 ajcvickers

@ajcvickers preview package 3.0.0-preview-0045-g9b6fc72764 is now live

mhutch avatar Jan 23 '24 06:01 mhutch

All: If you have been hitting this, then please try out the latest daily build of EF Core and let us know if the problem is fixed.

ajcvickers avatar Jan 25 '24 10:01 ajcvickers

All: If you have been hitting this, then please try out the latest daily build of EF Core and let us know if the problem is fixed.

Do the daily builds now require dotnet 9? I followed the instructions on the linked page but can't seem to get the daily build installed on a dotnet 8 based project

jcummings2 avatar Feb 09 '24 22:02 jcummings2

@jcummings2 EF9 should not require .NET 9 at this time. If you are seeing an issue with this, can you please attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.

ajcvickers avatar Feb 10 '24 11:02 ajcvickers

@jcummings2 EF9 should not require .NET 9 at this time. If you are seeing an issue with this, can you please attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.

I got it to work with .NET 8 but it was a subtle step that is at best implied on the daily builds instructions related to which version to use. Simply pasting the wildcard 9.0.0-* into the .csproj file didn't work but the build process complained about no such version available. In other words, the statement on the instructions that "Using wildcards will cause NuGet to pull the latest daily build whenever packages are restored" didn't seem true in my case.

However, after I went into the NuGet package manager in Visual Studio and selected "Latest prerelease 9.0.0-*" for each package then it would build and run. Maybe I missed a step but hopefully these details will help someone else.

jcummings2 avatar Feb 12 '24 21:02 jcummings2