2
votes

Following this tutorial it is possible to scaffold a database context using Entity Framework Core via the command line.

Scaffolding has some strange requirements

  • it needs an entry point aka main method (no scaffolding into class libraries)
  • the complete project has to be compileable (before scaffolding)

In my current project I need the model classes in a "shared project" (not directly a class library). The shared project does not have an entry point.

(I currently scaffold a lot since DB engineer updates the database model a lot in a database first approach).

In order to create some automated scaffolding task script I planed to automate the following tasks:

  • create a new, empty & temporay dot net command line application (it is buildable and has an entry point)
  • add required packages
  • scaffold the database context and model classes
  • move the generated classes to the library/shared project
  • delete the temporary project

So far I managed to automate the first points.

But I can't figure out a way how to add the ItemGroup DotNetCliToolReference to the xml of the .csproj file.

Is there any dotnet cli command that lets me add the DotNetCliToolReference and not only packages and project-to-project references?

Any other hints for me, please?

4

4 Answers

5
votes

As of EF Core 2.1 the reference is included in the .NET Core SDK this means you don't have to add the reference to the temp project.

https://blogs.msdn.microsoft.com/dotnet/2018/05/30/announcing-entity-framework-core-2-1/

The dotnet-ef commands now ship as part of the .NET Core SDK, so it will no longer be necessary to use DotNetCliToolReference in the project to be able to use migrations or to scaffold a DbContext from an existing database.

I have created a quick PowerShell script that is added to the classlib which then creates a temp project and scaffolds the dbcontext and cleans everything up at the end.

param(
[Parameter(Mandatory=$true)][string]$username,
[Parameter(Mandatory=$true)][string]$password,
[Parameter(Mandatory=$true)][string]$datasource,
[Parameter(Mandatory=$true)][string]$catalog,
[Parameter(Mandatory=$true)][string]$contextName
)

$workingDir = $PSScriptRoot;

Write-Host "Project dir= $workingDir";
Write-Host "Creating temp project to run scaffold on";
cd ..
mkdir temp
cd temp
dotnet new web
Write-Host "Done creating temp project";
Write-Host "Scaffolding dbcontext into project";
dotnet ef dbcontext scaffold "data source=$($datasource);initial catalog=$($catalog);user id=$($username);password=$($password);MultipleActiveResultSets=True;App=EntityFramework" Microsoft.EntityFrameworkCore.SqlServer --output-dir Entities --context $contextName --project temp.csproj
Write-Host "Done scaffolding dbcontext into temp project";
New-Item -ErrorAction Ignore -ItemType directory -Path "$workingDir/Entities";
Move-Item ./Entities/* "$workingDir/Entities" -force;
Write-Host "Scaffold completed! Starting clean-up";
cd ..
Remove-Item ./temp -force -Recurse;
cd $workingDir;
Write-Host "Clean-up completed!";

I'm sure the script can be improved but it works great as it is.

The script works as follows:

Let's say we run the script in the classlib directory: c:/test/classlib

  1. Store the current directory
  2. Create a temp web project: c:/test/temp
  3. Scaffold the DBContext
  4. Move the scaffolded items to the classlib (Be aware the script is set up to override the current Entities dir)
  5. Delete the temp project

You would still have to change the namespace to the correct one. Support for namespace on scaffold is currently on the list for 2.2 as far as I know. Hope it helps!

5
votes
  1. Install EntityFrameWorkCore.Sqlserver and EntityFrameWorkCore.Tools from Nuget

  2. In package Manager Console write:

    Scaffold-DbContext "Data Source=.;Initial Catalog="dbName";Integrated Security=True" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Project "Project's class library Name"
    
1
votes

Have you tried my "EF Core Power Tools" - they may be able to help you automate the process?

0
votes

dotnet add reference lib1/lib1.csproj

dotnet add package Newtonsoft.Json