dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.82k stars 3.2k forks source link

T4 Template Local Assembly References Suddenly Broken? #34494

Closed sunnylarr closed 2 months ago

sunnylarr commented 3 months ago

Hello, my team has been using EF Core Power Tools for a few months now with no major issues, but just recently we have noticed a bug when trying to run EF Power Tools reverse engineering using custom T4 template files.

After talking to @ErikEJ, the problem seems to be with EF Core itself since the same error occurs using the EF Core CLI tool.

Prior to the error, we would be able to successfully generate our EF context and model files using T4 templates that included assemblies located in our project's Libs\ folder. In this case, a local PluralizeService.Core.dll like so:

<#@ template hostSpecific="true" #>
<#@ assembly name="Microsoft.EntityFrameworkCore" #>
...
<#@ assembly name="MyProject\Libs\PluralizeService.Core.dll" #>
<#@ parameter name="Model" type="Microsoft.EntityFrameworkCore.Metadata.IModel" #>
<#@ parameter name="Options" type="Microsoft.EntityFrameworkCore.Scaffolding.ModelCodeGenerationOptions" #>
<#@ parameter name="NamespaceHint" type="System.String" #>
<#@ import namespace="System.Collections.Generic" #>
...
<#@ import namespace="Microsoft.Extensions.DependencyInjection" #>
<#@ import namespace="PluralizeService.Core" #>

However, within the last few months, we would be getting this error when trying to run EF Core Power Tools, or even the EF Core CLI with the following command: dotnet ef dbcontext scaffold "Data Source=tcp:<our_local_test_db_url>,1433;Initial Catalog=DEV_DB;Authentication=Active Directory Interactive;" Microsoft.EntityFrameworkCore.SqlServer

dotnet exec --depsfile C:\Users\LSun10\Repos\Common\MyProject\bin\Debug\net6.0\MyProject.deps.json --additionalprobingpath C:\Users\LSun10\.nuget\packages --runtimeconfig C:\Users\LSun10\Repos\Common\MyProject\bin\Debug\net6.0\MyProject.runtimeconfig.json C:\Users\LSun10\.dotnet\tools\.store\dotnet-ef\8.0.8\dotnet-ef\8.0.8\tools\net8.0\any\tools\netcoreapp2.0\any\ef.dll dbcontext scaffold "Data Source=tcp:sqlsrv-0107-cews-dev.database.windows.net,1433;Initial Catalog=DEV_CEWS;Authentication=Active Directory Interactive;" Microsoft.EntityFrameworkCore.SqlServer --assembly C:\Users\LSun10\Repos\Common\MyProject\bin\Debug\net6.0\MyProject.dll --project C:\Users\LSun10\Repos\Common\MyProject\MyProject.csproj --startup-assembly C:\Users\LSun10\Repos\Common\MyProject\bin\Debug\net6.0\MyProject.dll --startup-project C:\Users\LSun10\Repos\Common\MyProject\MyProject.csproj --project-dir C:\Users\LSun10\Repos\Common\MyProject\ --root-namespace MyProject --language C# --framework net6.0 --nullable --working-dir C:\Users\LSun10\Repos\Common\MyProject --verbose
Using assembly 'MyProject'.
Using startup assembly 'MyProject'.
Using application base 'C:\Users\LSun10\Repos\Common\MyProject\bin\Debug\net6.0'.
Using working directory 'C:\Users\LSun10\Repos\Common\MyProject'.
Using root namespace 'MyProject'.
Using project directory 'C:\Users\LSun10\Repos\Common\MyProject\'.
Remaining arguments: .
Finding design-time services referenced by assembly 'MyProject'...
Finding design-time services referenced by assembly 'MyProject'...
No referenced design-time services were found.
Finding design-time services for provider 'Microsoft.EntityFrameworkCore.SqlServer'...
Using design-time services from provider 'Microsoft.EntityFrameworkCore.SqlServer'.
Finding IDesignTimeServices implementations in assembly 'MyProject'...
No design-time services were found.

...

(A lot of "Found a Table/Column" logs here)

...

error CS0006: Metadata file 'MyProject\Libs\PluralizeService.Core.dll' could not be found

Microsoft.EntityFrameworkCore.Design.OperationException: Processing 'C:\Users\LSun10\Repos\Common\MyProject\CodeTemplates\EFCore\DbContext.t4' failed.
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.TextTemplatingModelGenerator.HandleErrors(TextTemplatingEngineHost host)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.TextTemplatingModelGenerator.GenerateModel(IModel model, ModelCodeGenerationOptions options)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.ScaffoldModel(String connectionString, DatabaseModelFactoryOptions databaseOptions, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions)
   at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerable`1 schemas, IEnumerable`1 tables, String modelNamespace, String contextNamespace, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames, Boolean suppressOnConfiguring, Boolean noPluralize)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable`1 schemaFilters, IEnumerable`1 tableFilters, String modelNamespace, String contextNamespace, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames, Boolean suppressOnConfiguring, Boolean noPluralize)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)

Microsoft.EntityFrameworkCore.Design.OperationException: Processing 'C:\Users\LSun123\Repos\Common\MyProject\.\CodeTemplates\EFCore\DbContext.t4' failed.

One thing to note is that absolute pathing does work, such as <#@ assembly name="C:\Users\LSun10\Repos\Common\MyProject\Libs\PluralizeService.Core.dll" #>

I am also not able to use any VS variables such as $(SolutionDir) or custom project properties as described in the T4 guide here

I also noticed that, when trying to print the working directory from the DbContext.t4 file, it would return C:\Windows\system32, so it is not respecting the project's working directory anymore.

Any reason why the template generation logic changed? Again, these template files were working fine a few months ago and are now suddenly broken. Any help would be greatly appreciated. Thanks!

Include provider and version information

EF Core version: 8.0.8 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 6.0 Operating system: IDE: Visual Studio 2022 17.10.0

sunnylarr commented 3 months ago

Any advice or insight at all in to the issue? Are there workarounds that don't involve hard coded paths or the need to install the DLL in the global assembly cache?

AndriySvyryd commented 3 months ago

@sunnylarr Can you try upgrading to 9.0.0-preview.7.24405.3? It references a new version of Mono.TextTemplating that contains a fix that might be relevant here.

AndriySvyryd commented 2 months ago

EF Team Triage: Closing this issue as the requested additional details have not been provided and we have been unable to reproduce it.

BTW this is a canned response and may have info or details that do not directly apply to this particular issue. While we'd like to spend the time to uniquely address every incoming issue, we get a lot traffic on the EF projects and that is not practical. To ensure we maximize the time we have to work on fixing bugs, implementing new features, etc. we use canned responses for common triage decisions.