Skip to content

Commit

Permalink
Add Microsoft.EntityFrameworkCore.Templates (#28678)
Browse files Browse the repository at this point in the history
Adds a new package that can be installed via `dotnet new`:

    dotnet new install Microsoft.EntityFrameworkCore.Templates::7.0.0-*

For now, it just includes a single item template that will add the default T4 templates used by `dotnet ef dbcontext scaffold`.

    dotnet new ef-templates

You can then tweak the templates and they'll automatically be used when scaffolding.

    dotnet ef dbcontext scaffold Filename=northwind.db Microsoft.EntityFrameworkCore.Sqlite

Resolves #4038
  • Loading branch information
bricelam authored Aug 11, 2022
1 parent 5b27554 commit 7a9756c
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 2 deletions.
9 changes: 8 additions & 1 deletion All.sln
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.AspNet.Sqlite.Functi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.AspNet.InMemory.FunctionalTests", "test\EFCore.AspNet.InMemory.FunctionalTests\EFCore.AspNet.InMemory.FunctionalTests.csproj", "{F1B2E5A0-8C74-414A-B262-353FEE325E9F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EFCore.Trimming.Tests", "test\EFCore.Trimming.Tests\EFCore.Trimming.Tests.csproj", "{933C8662-817C-4F45-B98B-6557E28F7BB1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.Trimming.Tests", "test\EFCore.Trimming.Tests\EFCore.Trimming.Tests.csproj", "{933C8662-817C-4F45-B98B-6557E28F7BB1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.Templates", "src\EFCore.Templates\EFCore.Templates.csproj", "{1FE385D8-8F8B-4EC9-A1A9-AFCC38B8546C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -325,6 +327,10 @@ Global
{933C8662-817C-4F45-B98B-6557E28F7BB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{933C8662-817C-4F45-B98B-6557E28F7BB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{933C8662-817C-4F45-B98B-6557E28F7BB1}.Release|Any CPU.Build.0 = Release|Any CPU
{1FE385D8-8F8B-4EC9-A1A9-AFCC38B8546C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1FE385D8-8F8B-4EC9-A1A9-AFCC38B8546C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FE385D8-8F8B-4EC9-A1A9-AFCC38B8546C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FE385D8-8F8B-4EC9-A1A9-AFCC38B8546C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -379,6 +385,7 @@ Global
{CC93C465-F5AC-4CB9-A064-3675955962F4} = {258D5057-81B9-40EC-A872-D21E27452749}
{F1B2E5A0-8C74-414A-B262-353FEE325E9F} = {258D5057-81B9-40EC-A872-D21E27452749}
{933C8662-817C-4F45-B98B-6557E28F7BB1} = {258D5057-81B9-40EC-A872-D21E27452749}
{1FE385D8-8F8B-4EC9-A1A9-AFCC38B8546C} = {CE6B50B2-34AE-44C9-940A-4E48C3E1B3BC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {285A5EB4-BCF4-40EB-B9E1-DF6DBCB5E705}
Expand Down
3 changes: 2 additions & 1 deletion EFCore.Tools.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"projects": [
"src\\dotnet-ef\\dotnet-ef.csproj",
"src\\ef\\ef.csproj",
"src\\EFCore.Design\\EFCore.Design.csproj",
"src\\EFCore.Design\\EFCore.Design.csproj",
"src\\EFCore.Templates\\EFCore.Templates.csproj",
"src\\EFCore.Tools\\EFCore.Tools.csproj",
"test\\dotnet-ef.Tests\\dotnet-ef.Tests.csproj",
"test\\ef.Tests\\ef.Tests.csproj",
Expand Down
131 changes: 131 additions & 0 deletions src/EFCore.Templates/EFCore.Templates.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageType>Template</PackageType>
<PackageId>Microsoft.EntityFrameworkCore.Templates</PackageId>
<Description>
Entity Framework Core templates for dotnet-new.

Enables these commonly used templates:
ef-templates
</Description>
<TargetFramework>netstandard2.0</TargetFramework>
<IncludeContentInPack>true</IncludeContentInPack>
<IncludeBuildOutput>false</IncludeBuildOutput>
<ContentTargetFolders>content</ContentTargetFolders>
<NoWarn>$(NoWarn);NU5128</NoWarn>
<NoDefaultExcludes>true</NoDefaultExcludes>
<IncludeSymbols>false</IncludeSymbols>
</PropertyGroup>

<ItemGroup>
<Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" />
<Compile Remove="**\*" />
</ItemGroup>

<ItemGroup>
<GeneratedContent Include="..\EFCore.Design\Scaffolding\Internal\CSharpDbContextGenerator.tt">
<PackagePath>content\templates\ef-templates\CodeTemplates\EFCore\DbContext.t4</PackagePath>
<IsDbContext>true</IsDbContext>
</GeneratedContent>
<GeneratedContent Include="..\EFCore.Design\Scaffolding\Internal\CSharpEntityTypeGenerator.tt">
<PackagePath>content\templates\ef-templates\CodeTemplates\EFCore\EntityType.t4</PackagePath>
</GeneratedContent>
</ItemGroup>

<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>

<UsingTask TaskName="PatchTemplate" TaskFactory="RoslynCodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup>
<TemplateFile ParameterType="System.String" Required="true" />
<OutputPath ParameterType="System.String" Required="true" />
<IsDbContext ParameterType="System.Boolean" />
<VersionPrefix ParameterType="System.String" />
</ParameterGroup>
<Task>
<Using Namespace="System.IO" />
<Code Type="Fragment" Language="cs">
<![CDATA[
const string importLine = @"<#@ import namespace=""Microsoft.EntityFrameworkCore.Infrastructure"" #>";
var linePragmasRemoved = false;
var importAdded = !IsDbContext;
var versionCheckAdded = !IsDbContext;
Directory.CreateDirectory(Path.GetDirectoryName(OutputPath));
using (var reader = new StreamReader(TemplateFile))
using (var writer = new StreamWriter(OutputPath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (!linePragmasRemoved
&& line.StartsWith("<#@ template "))
{
writer.WriteLine(line.Replace(@" linePragmas=""false""", ""));
linePragmasRemoved = true;
}
else if (!importAdded
&& line.StartsWith("<#@ import ")
&& !line.Contains(@" namespace=""System.")
&& string.Compare(line, importLine) > 0
&& !line.Contains(@" namespace=""Microsoft.EntityFrameworkCore"""))
{
writer.WriteLine(importLine);
writer.WriteLine(line);
importAdded = true;
}
else if (!versionCheckAdded
&& line == "<#")
{
var version = new Version(VersionPrefix);
writer.WriteLine(line);
writer.WriteLine(@" if (!ProductInfo.GetVersion().StartsWith(""" + version.Major + "." + version.Minor + @"""))");
writer.WriteLine(@" {");
writer.WriteLine(@" Warning(""Your templates were created using an older version of Entity Framework. Additional features and bug fixes may be available. See https://aka.ms/efcore-docs-updating-templates for more information."");");
writer.WriteLine(@" }");
writer.WriteLine();
versionCheckAdded = true;
}
else
{
writer.WriteLine(line);
}
}
}
if (!linePragmasRemoved
|| !importAdded
|| !versionCheckAdded)
{
Log.LogError("Failed to patch the template files. Update the code in EFCore.Templates.csproj");
return false;
}
]]>
</Code>
</Task>
</UsingTask>

<PropertyGroup>
<BeforePack>$(BeforePack);GenerateContent</BeforePack>
</PropertyGroup>

<Target Name="GenerateContent">
<PatchTemplate TemplateFile="%(GeneratedContent.Identity)"
OutputPath="$(IntermediateOutputPath)%(GeneratedContent.PackagePath)"
IsDbContext="%(GeneratedContent.IsDbContext)"
VersionPrefix="$(VersionPrefix)"/>
<ItemGroup>
<Content Include="$(IntermediateOutputPath)%(GeneratedContent.PackagePath)" PackagePath="$([System.IO.Path]::GetDirectoryName(%(GeneratedContent.PackagePath)))" />
</ItemGroup>
</Target>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "Microsoft",
"classifications": [ "EFCore", "Scaffolding" ],
"identity": "Microsoft.EntityFrameworkCore.Templates.ef-templates",
"name": "Entity Framework Core Scaffolding Templates",
"shortName": "ef-templates",
"tags": {
"language": "C#",
"type": "item"
}
}

0 comments on commit 7a9756c

Please sign in to comment.