Merge repo 'aspnet/EntityFramework.Tools' in

Resolves #7624
This commit is contained in:
Brice Lambson 2017-03-13 12:15:10 -07:00
Родитель c402d73796
Коммит 7c64310a66
91 изменённых файлов: 7643 добавлений и 4 удалений

Просмотреть файл

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26214.1
VisualStudioVersion = 15.0.26228.4
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore", "src\EFCore\EFCore.csproj", "{715C38E9-B2F5-4DB2-8025-0C6492DEBDD4}"
EndProject
@ -69,6 +69,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.Benchmarks.EFCore",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.Benchmarks.EF6", "test\EFCore.Benchmarks.EF6\EFCore.Benchmarks.EF6.csproj", "{477EBF1E-A4B8-4D60-8681-5D6D5BB42CE1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-ef", "src\dotnet-ef\dotnet-ef.csproj", "{2D66A1DA-D102-4DD9-960B-7D863BBB53DE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ef", "src\ef\ef.csproj", "{4F7C93F3-A30F-4061-804C-32293DC256A1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.Tools", "src\EFCore.Tools\EFCore.Tools.csproj", "{87ADBDB5-CA57-4EAB-9A8A-5E89480C9C6D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EFCore.Tools.DotNet", "src\EFCore.Tools.DotNet\EFCore.Tools.DotNet.csproj", "{31ED3EA7-8270-478D-935D-0067BD7935B7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-ef.Tests", "test\dotnet-ef.Tests\dotnet-ef.Tests.csproj", "{27018CE2-C235-439C-80F2-C573C8904892}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ef.Tests", "test\ef.Tests\ef.Tests.csproj", "{935B51B9-A9B9-4DA2-93A2-663D3BCEAA83}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -199,6 +211,30 @@ Global
{477EBF1E-A4B8-4D60-8681-5D6D5BB42CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{477EBF1E-A4B8-4D60-8681-5D6D5BB42CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{477EBF1E-A4B8-4D60-8681-5D6D5BB42CE1}.Release|Any CPU.Build.0 = Release|Any CPU
{2D66A1DA-D102-4DD9-960B-7D863BBB53DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D66A1DA-D102-4DD9-960B-7D863BBB53DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D66A1DA-D102-4DD9-960B-7D863BBB53DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D66A1DA-D102-4DD9-960B-7D863BBB53DE}.Release|Any CPU.Build.0 = Release|Any CPU
{4F7C93F3-A30F-4061-804C-32293DC256A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F7C93F3-A30F-4061-804C-32293DC256A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F7C93F3-A30F-4061-804C-32293DC256A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F7C93F3-A30F-4061-804C-32293DC256A1}.Release|Any CPU.Build.0 = Release|Any CPU
{87ADBDB5-CA57-4EAB-9A8A-5E89480C9C6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{87ADBDB5-CA57-4EAB-9A8A-5E89480C9C6D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{87ADBDB5-CA57-4EAB-9A8A-5E89480C9C6D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{87ADBDB5-CA57-4EAB-9A8A-5E89480C9C6D}.Release|Any CPU.Build.0 = Release|Any CPU
{31ED3EA7-8270-478D-935D-0067BD7935B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{31ED3EA7-8270-478D-935D-0067BD7935B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31ED3EA7-8270-478D-935D-0067BD7935B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31ED3EA7-8270-478D-935D-0067BD7935B7}.Release|Any CPU.Build.0 = Release|Any CPU
{27018CE2-C235-439C-80F2-C573C8904892}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27018CE2-C235-439C-80F2-C573C8904892}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27018CE2-C235-439C-80F2-C573C8904892}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27018CE2-C235-439C-80F2-C573C8904892}.Release|Any CPU.Build.0 = Release|Any CPU
{935B51B9-A9B9-4DA2-93A2-663D3BCEAA83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{935B51B9-A9B9-4DA2-93A2-663D3BCEAA83}.Debug|Any CPU.Build.0 = Debug|Any CPU
{935B51B9-A9B9-4DA2-93A2-663D3BCEAA83}.Release|Any CPU.ActiveCfg = Release|Any CPU
{935B51B9-A9B9-4DA2-93A2-663D3BCEAA83}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -235,5 +271,11 @@ Global
{E3146D04-6E87-41C1-A2E3-F2D7CDFB9B99} = {258D5057-81B9-40EC-A872-D21E27452749}
{049A9748-B3CE-4412-B455-F7108B3BA239} = {258D5057-81B9-40EC-A872-D21E27452749}
{477EBF1E-A4B8-4D60-8681-5D6D5BB42CE1} = {258D5057-81B9-40EC-A872-D21E27452749}
{2D66A1DA-D102-4DD9-960B-7D863BBB53DE} = {CE6B50B2-34AE-44C9-940A-4E48C3E1B3BC}
{4F7C93F3-A30F-4061-804C-32293DC256A1} = {CE6B50B2-34AE-44C9-940A-4E48C3E1B3BC}
{87ADBDB5-CA57-4EAB-9A8A-5E89480C9C6D} = {CE6B50B2-34AE-44C9-940A-4E48C3E1B3BC}
{31ED3EA7-8270-478D-935D-0067BD7935B7} = {CE6B50B2-34AE-44C9-940A-4E48C3E1B3BC}
{27018CE2-C235-439C-80F2-C573C8904892} = {258D5057-81B9-40EC-A872-D21E27452749}
{935B51B9-A9B9-4DA2-93A2-663D3BCEAA83} = {258D5057-81B9-40EC-A872-D21E27452749}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -1,4 +1,16 @@
{
"adx": {
"rules": [
"AdxVerificationCompositeRule"
],
"packages": {
"Microsoft.EntityFrameworkCore.Tools.DotNet": {
"packageTypes": [
"DotnetCliTool"
]
}
}
},
"Default": {
"rules": [
"DefaultCompositeRule"

Просмотреть файл

@ -0,0 +1,28 @@
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<NuspecFile>$(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec</NuspecFile>
<NoPackageAnalysis>true</NoPackageAnalysis>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\dotnet-ef\dotnet-ef.csproj" />
<ProjectReference Include="..\ef\ef.csproj" />
</ItemGroup>
<Target Name="SetPackageProperties" BeforeTargets="GenerateNuspec">
<PropertyGroup>
<NuspecProperties>version=$(PackageVersion);configuration=$(Configuration)</NuspecProperties>
</PropertyGroup>
</Target>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<Target Name="Compile" />
<Target Name="CopyFilesToOutputDirectory" />
</Project>

Просмотреть файл

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Microsoft.EntityFrameworkCore.Tools.DotNet</id>
<version>$version$</version>
<authors>Microsoft</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Entity Framework Core .NET Command Line Tools. Includes dotnet-ef.</description>
<tags>Entity Framework Core,entity-framework-core,EF,Data,O/RM</tags>
<repository type="git" url="https://github.com/aspnet/EntityFramework.Tools.git" />
<serviceable>true</serviceable>
<packageTypes>
<packageType name="DotnetCliTool" />
</packageTypes>
<dependencies>
<group targetFramework=".NETCoreApp1.0">
<dependency id="Microsoft.NETCore.App" version="1.0.0" exclude="Build,Analyzers" />
<dependency id="Newtonsoft.Json" version="9.0.1" exclude="Build,Analyzers" />
</group>
</dependencies>
</metadata>
<files>
<file src="../dotnet-ef/bin/$configuration$/netcoreapp1.0/dotnet-ef.dll" target="lib/netcoreapp1.0/" />
<file src="../dotnet-ef/bin/$configuration$/netcoreapp1.0/dotnet-ef.runtimeconfig.json" target="lib/netcoreapp1.0/" />
<file src="../ef/bin/$configuration$/net451/ef.exe" target="tools/net451/" />
<file src="../ef/bin/x86/$configuration$/net451/ef.x86.exe" target="tools/net451/" />
<file src="../ef/bin/$configuration$/netcoreapp1.0/ef.dll" target="tools/netcoreapp1.0/" />
<file src="../ef/bin/$configuration$/netcoreapp1.0/ef.runtimeconfig.json" target="tools/netcoreapp1.0/" />
<file src="prefercliruntime" target="prefercliruntime" />
</files>
</package>

Просмотреть файл

Просмотреть файл

@ -0,0 +1,28 @@
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFrameworks>net451;netcoreapp1.0</TargetFrameworks>
<NuspecFile>$(MSBuildThisFileDirectory)$(MSBuildProjectName).nuspec</NuspecFile>
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
<NoPackageAnalysis>true</NoPackageAnalysis>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ef\ef.csproj" />
</ItemGroup>
<Target Name="SetPackageProperties" BeforeTargets="GenerateNuspec">
<PropertyGroup>
<NuspecProperties>version=$(PackageVersion);configuration=$(Configuration)</NuspecProperties>
</PropertyGroup>
</Target>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
<Target Name="Compile" />
<Target Name="CopyFilesToOutputDirectory" />
</Project>

Просмотреть файл

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Microsoft.EntityFrameworkCore.Tools</id>
<version>$version$</version>
<authors>Microsoft</authors>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<developmentDependency>true</developmentDependency>
<description>Entity Framework Core Package Manager Console Tools. Includes Scaffold-DbContext, Add-Migration, and Update-Database.</description>
<tags>Entity Framework Core,entity-framework-core,EF,Data,O/RM</tags>
<serviceable>true</serviceable>
<repository type="git" url="https://github.com/aspnet/EntityFramework.Tools.git" />
<dependencies>
<group targetFramework=".NETStandard1.3">
<dependency id="Microsoft.EntityFrameworkCore.Design" version="$version$" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETFramework4.5.1">
<dependency id="Microsoft.EntityFrameworkCore.Design" version="$version$" exclude="Build,Analyzers" />
</group>
</dependencies>
</metadata>
<files>
<file src="lib/**/*" target="" />
<file src="tools/**/*" target=""/>
<file src="../ef/bin/$configuration$/net451/ef.exe" target="tools/net451/" />
<file src="../ef/bin/x86/$configuration$/net451/ef.x86.exe" target="tools/net451/" />
<file src="../ef/bin/$configuration$/netcoreapp1.0/ef.dll" target="tools/netcoreapp1.0/" />
<file src="../ef/bin/$configuration$/netcoreapp1.0/ef.runtimeconfig.json" target="tools/netcoreapp1.0/" />
</files>
</package>

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -0,0 +1,87 @@
@{
# Script module or binary module file associated with this manifest
ModuleToProcess = 'EntityFrameworkCore.PowerShell2.psm1'
# Version number of this module.
ModuleVersion = '1.1.0'
# ID used to uniquely identify this module
GUID = '2de7c7fd-c848-41d7-8634-37fed4d3bb36'
# Author of this module
Author = 'Entity Framework Team'
# Company or vendor of this module
CompanyName = 'Microsoft Corporation'
# Copyright statement for this module
Copyright = '(c) .NET Foundation. All rights reserved.'
# Description of the functionality provided by this module
Description = 'Entity Framework Core Package Manager Console Tools'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '1.0'
# Name of the Windows PowerShell host required by this module
PowerShellHostName = 'Package Manager Host'
# Minimum version of the Windows PowerShell host required by this module
PowerShellHostVersion = '1.2'
# Minimum version of the .NET Framework required by this module
DotNetFrameworkVersion = '4.0'
# Minimum version of the common language runtime (CLR) required by this module
CLRVersion = ''
# Processor architecture (None, X86, Amd64, IA64) required by this module
ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
RequiredModules = 'NuGet'
# Assemblies that must be loaded prior to importing this module
RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module
ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
FormatsToProcess = @()
# Modules to import as nested modules of the module specified in ModuleToProcess
NestedModules = @()
# Functions to export from this module
FunctionsToExport = (
'Add-Migration',
'Drop-Database',
'Enable-Migrations',
'Remove-Migration',
'Scaffold-DbContext',
'Script-Migration',
'Update-Database'
)
# Cmdlets to export from this module
CmdletsToExport = @()
# Variables to export from this module
VariablesToExport = @()
# Aliases to export from this module
AliasesToExport = @()
# List of all modules packaged with this module
ModuleList = @()
# List of all files packaged with this module
FileList = @()
# Private data to pass to the module specified in ModuleToProcess
PrivateData = ''
}

Просмотреть файл

@ -0,0 +1,53 @@
$ErrorActionPreference = 'Stop'
$versionErrorMessage = 'The Entity Framework Core Package Manager Console Tools don''t support PowerShell version ' +
"$($PSVersionTable.PSVersion). Upgrade to PowerShell version 3.0 or higher, restart Visual Studio, and try again."
function Add-Migration
{
WarnIfEF6 'Add-Migration'
throw $versionErrorMessage
}
function Drop-Database
{
throw $versionErrorMessage
}
function Enable-Migrations
{
WarnIfEF6 'Enable-Migrations'
throw $versionErrorMessage
}
function Remove-Migration
{
throw $versionErrorMessage
}
function Scaffold-DbContext
{
throw $versionErrorMessage
}
function Script-Migration
{
throw $versionErrorMessage
}
function Update-Database
{
WarnIfEF6 'Update-Database'
throw $versionErrorMessage
}
function WarnIfEF6($cmdlet)
{
if (Get-Module 'EntityFramework')
{
Write-Warning "Both Entity Framework Core and Entity Framework 6 are installed. The Entity Framework Core tools are running. Use 'EntityFramework\$cmdlet' for Entity Framework 6."
}
}

Просмотреть файл

@ -0,0 +1,87 @@
@{
# Script module or binary module file associated with this manifest
ModuleToProcess = 'EntityFrameworkCore.psm1'
# Version number of this module.
ModuleVersion = '1.1.0'
# ID used to uniquely identify this module
GUID = 'c126fb40-c0f1-43ae-8dd0-06bb50512eb2'
# Author of this module
Author = 'Entity Framework Team'
# Company or vendor of this module
CompanyName = 'Microsoft Corporation'
# Copyright statement for this module
Copyright = '(c) .NET Foundation. All rights reserved.'
# Description of the functionality provided by this module
Description = 'Entity Framework Core Package Manager Console Tools'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '3.0'
# Name of the Windows PowerShell host required by this module
PowerShellHostName = 'Package Manager Host'
# Minimum version of the Windows PowerShell host required by this module
PowerShellHostVersion = '1.2'
# Minimum version of the .NET Framework required by this module
DotNetFrameworkVersion = '4.0'
# Minimum version of the common language runtime (CLR) required by this module
CLRVersion = ''
# Processor architecture (None, X86, Amd64, IA64) required by this module
ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
RequiredModules = 'NuGet'
# Assemblies that must be loaded prior to importing this module
RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module
ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
FormatsToProcess = @()
# Modules to import as nested modules of the module specified in ModuleToProcess
NestedModules = @()
# Functions to export from this module
FunctionsToExport = (
'Add-Migration',
'Drop-Database',
'Enable-Migrations',
'Remove-Migration',
'Scaffold-DbContext',
'Script-Migration',
'Update-Database'
)
# Cmdlets to export from this module
CmdletsToExport = @()
# Variables to export from this module
VariablesToExport = @()
# Aliases to export from this module
AliasesToExport = @()
# List of all modules packaged with this module
ModuleList = @()
# List of all files packaged with this module
FileList = @()
# Private data to pass to the module specified in ModuleToProcess
PrivateData = ''
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,41 @@

_/\__
---==/ \\
___ ___ |. \|\
| __|| __| | ) \\\
| _| | _| \_/ | //|\\
|___||_| / \\\/\\
TOPIC
about_EntityFrameworkCore
SHORT DESCRIPTION
Provides information about the Entity Framework Core Package Manager Console Tools.
LONG DESCRIPTION
This topic describes the Entity Framework Core Package Manager Console Tools. See https://docs.efproject.net for
information on Entity Framework Core.
The following Entity Framework Core commands are available.
Cmdlet Description
-------------------------- ---------------------------------------------------
Add-Migration Adds a new migration.
Drop-Database Drops the database.
Remove-Migration Removes the last migration.
Scaffold-DbContext Scaffolds a DbContext and entity types for a database.
Script-Migration Generates a SQL script from migrations.
Update-Database Updates the database to a specified migration.
SEE ALSO
Add-Migration
Drop-Database
Remove-Migration
Scaffold-DbContext
Script-Migration
Update-Database

Просмотреть файл

@ -0,0 +1,24 @@
param($installPath, $toolsPath, $package, $project)
if ($PSVersionTable.PSVersion.Major -lt 3)
{
# This section needs to support PS2 syntax
# Use $toolsPath because PS2 does not support $PSScriptRoot
$env:PSModulePath = $env:PSModulePath + ';$toolsPath'
# Import a "dummy" module that contains matching functions that throw on PS2
Import-Module (Join-Path $toolsPath 'EntityFrameworkCore.PowerShell2.psd1') -DisableNameChecking
throw "PowerShell version $($PSVersionTable.PSVersion) is not supported. Please upgrade PowerShell to 3.0 or " +
'greater and restart Visual Studio.'
}
else
{
if (Get-Module 'EntityFrameworkCore')
{
Remove-Module 'EntityFrameworkCore'
}
Import-Module (Join-Path $PSScriptRoot 'EntityFrameworkCore.psd1') -DisableNameChecking
}

Просмотреть файл

@ -0,0 +1,5 @@
param($installPath, $toolsPath, $package, $project)
Write-Host
Write-Host 'Type ''get-help EntityFrameworkCore'' to see all available Entity Framework Core commands.'
Write-Host

Просмотреть файл

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Collections.Concurrent" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Collections" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.Annotations" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.EventBasedAsync" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.Contracts" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.Debug" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.Tools" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.Tracing" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Dynamic.Runtime" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Globalization" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq.Expressions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq.Parallel" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq.Queryable" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.NetworkInformation" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Primitives" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Requests" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.WebHeaderCollection" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ObjectModel" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Emit" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Emit.ILGeneration" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Emit.Lightweight" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Extensions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Primitives" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Resources.ResourceManager" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Extensions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Handles" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices.WindowsRuntime" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Numerics" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Serialization.Json" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Serialization.Primitives" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Serialization.Xml" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Principal" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.Duplex" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.Http" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.NetTcp" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.Primitives" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.Security" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.Extensions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.RegularExpressions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Parallel" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Timer" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.ReaderWriter" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.XDocument" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.XmlSerializer" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Collections.Concurrent" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Collections" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.Annotations" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ComponentModel.EventBasedAsync" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.Contracts" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.Debug" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.Tools" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.Tracing" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Dynamic.Runtime" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Globalization" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq.Expressions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq.Parallel" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Linq.Queryable" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.NetworkInformation" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Primitives" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Requests" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.WebHeaderCollection" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ObjectModel" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Emit" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Emit.ILGeneration" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Emit.Lightweight" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Extensions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Reflection.Primitives" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Resources.ResourceManager" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Extensions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Handles" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.InteropServices.WindowsRuntime" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Numerics" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Serialization.Json" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Serialization.Primitives" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.Serialization.Xml" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Principal" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.Duplex" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.Http" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.NetTcp" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.Primitives" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ServiceModel.Security" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encoding.Extensions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.RegularExpressions" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Parallel" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Timer" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.ReaderWriter" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.XDocument" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.XmlSerializer" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="4.1.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

Просмотреть файл

@ -0,0 +1,17 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal class ProjectCommandBase : EnvironmentCommandBase
{
public override void Configure(CommandLineApplication command)
{
new ProjectOptions().Configure(command);
base.Configure(command);
}
}
}

98
src/dotnet-ef/Exe.cs Normal file
Просмотреть файл

@ -0,0 +1,98 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal static class Exe
{
public static int Run(string executable, IReadOnlyList<string> args)
{
var arguments = ToArguments(args);
Reporter.WriteVerbose(executable + " " + arguments);
var build = Process.Start(
new ProcessStartInfo
{
FileName = executable,
Arguments = arguments,
UseShellExecute = false
});
build.WaitForExit();
return build.ExitCode;
}
private static string ToArguments(IReadOnlyList<string> args)
{
var builder = new StringBuilder();
for (var i = 0; i < args.Count; i++)
{
if (i != 0)
{
builder.Append(" ");
}
if (args[i].IndexOf(' ') == -1)
{
builder.Append(args[i]);
continue;
}
builder.Append("\"");
var pendingBackslashs = 0;
for (var j = 0; j < args[i].Length; j++)
{
switch (args[i][j])
{
case '\"':
if (pendingBackslashs != 0)
{
builder.Append('\\', pendingBackslashs * 2);
pendingBackslashs = 0;
}
builder.Append("\\\"");
break;
case '\\':
pendingBackslashs++;
break;
default:
if (pendingBackslashs != 0)
{
if (pendingBackslashs == 1)
{
builder.Append("\\");
}
else
{
builder.Append('\\', pendingBackslashs * 2);
}
pendingBackslashs = 0;
}
builder.Append(args[i][j]);
break;
}
}
if (pendingBackslashs != 0)
{
builder.Append('\\', pendingBackslashs * 2);
}
builder.Append("\"");
}
return builder.ToString();
}
}
}

41
src/dotnet-ef/Program.cs Normal file
Просмотреть файл

@ -0,0 +1,41 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal static class Program
{
private static int Main(string[] args)
{
var app = new CommandLineApplication(throwOnUnexpectedArg: false)
{
Name = "dotnet ef"
};
new RootCommand().Configure(app);
try
{
return app.Execute(args);
}
catch (Exception ex)
{
if (ex is CommandException || ex is CommandParsingException)
{
Reporter.WriteVerbose(ex.ToString());
}
else
{
Reporter.WriteInformation(ex.ToString());
}
Reporter.WriteError(ex.Message);
return 1;
}
}
}
}

164
src/dotnet-ef/Project.cs Normal file
Просмотреть файл

@ -0,0 +1,164 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal class Project
{
private readonly string _file;
private readonly string _framework;
private readonly string _configuration;
public Project(string file, string framework, string configuration)
{
Debug.Assert(!string.IsNullOrEmpty(file), "file is null or empty.");
_file = file;
_framework = framework;
_configuration = configuration;
ProjectName = Path.GetFileName(file);
}
public string ProjectName { get; }
public string AssemblyName { get; set; }
public string OutputPath { get; set; }
public string PlatformTarget { get; set; }
public string ProjectAssetsFile { get; set; }
public string ProjectDir { get; set; }
public string RootNamespace { get; set; }
public string TargetFileName { get; set; }
public string TargetFrameworkMoniker { get; set; }
public static Project FromFile(
string file,
string buildExtensionsDir,
string framework = null,
string configuration = null)
{
Debug.Assert(!string.IsNullOrEmpty(file), "file is null or empty.");
if (buildExtensionsDir == null)
{
buildExtensionsDir = Path.Combine(Path.GetDirectoryName(file), "obj");
}
var efTargetsPath = Path.Combine(
buildExtensionsDir,
Path.GetFileName(file) + ".EntityFrameworkCore.targets");
if (!File.Exists(efTargetsPath))
{
Reporter.WriteVerbose(Resources.WritingFile(efTargetsPath));
using (var input = typeof(Resources).GetTypeInfo().Assembly.GetManifestResourceStream(
"Microsoft.EntityFrameworkCore.Tools.Resources.EntityFrameworkCore.targets"))
using (var output = File.OpenWrite(efTargetsPath))
{
input.CopyTo(output);
}
}
IDictionary<string, string> metadata;
var metadataFile = Path.GetTempFileName();
try
{
var propertyArg = "/property:EFProjectMetadataFile=" + metadataFile;
if (configuration != null)
{
propertyArg += ";TargetFramework=" + framework;
}
if (configuration != null)
{
propertyArg += ";Configuration=" + configuration;
}
var args = new List<string>
{
"msbuild",
"/target:GetEFProjectMetadata",
propertyArg,
"/verbosity:quiet",
"/nologo"
};
if (file != null)
{
args.Add(file);
}
var exitCode = Exe.Run("dotnet", args);
if (exitCode != 0)
{
throw new CommandException(Resources.GetMetadataFailed);
}
metadata = File.ReadLines(metadataFile).Select(l => l.Split(new[] { ':' }, 2))
.ToDictionary(s => s[0], s => s[1].TrimStart());
}
finally
{
File.Delete(metadataFile);
}
var platformTarget = metadata["PlatformTarget"];
if (platformTarget.Length == 0)
{
platformTarget = metadata["Platform"];
}
return new Project(file, framework, configuration)
{
AssemblyName = metadata["AssemblyName"],
OutputPath = metadata["OutputPath"],
PlatformTarget = platformTarget,
ProjectAssetsFile = metadata["ProjectAssetsFile"],
ProjectDir = metadata["ProjectDir"],
RootNamespace = metadata["RootNamespace"],
TargetFileName = metadata["TargetFileName"],
TargetFrameworkMoniker = metadata["TargetFrameworkMoniker"]
};
}
public void Build()
{
var args = new List<string>();
args.Add("build");
if (_file != null)
{
args.Add(_file);
}
// TODO: Only build for the first framework when unspecified
if (_framework != null)
{
args.Add("--framework");
args.Add(_framework);
}
if (_configuration != null)
{
args.Add("--configuration");
args.Add(_configuration);
}
args.Add("/verbosity:quiet");
args.Add("/nologo");
var exitCode = Exe.Run("dotnet", args);
if (exitCode != 0)
{
throw new CommandException(Resources.BuildFailed);
}
}
}
}

Просмотреть файл

@ -0,0 +1,41 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal class ProjectOptions
{
private CommandOption _project;
private CommandOption _startupProject;
private CommandOption _framework;
private CommandOption _configuration;
private CommandOption _msbuildprojectextensionspath;
public CommandOption Project
=> _project;
public CommandOption StartupProject
=> _startupProject;
public CommandOption Framework
=> _framework;
public CommandOption Configuration
=> _configuration;
public CommandOption MSBuildProjectExtensionsPath
=> _msbuildprojectextensionspath;
public void Configure(CommandLineApplication command)
{
_project = command.Option("-p|--project <PROJECT>", Resources.ProjectDescription);
_startupProject = command.Option("-s|--startup-project <PROJECT>", Resources.StartupProjectDescription);
_framework = command.Option("--framework <FRAMEWORK>", Resources.FrameworkDescription);
_configuration = command.Option("--configuration <CONFIGURATION>", Resources.ConfigurationDescription);
_msbuildprojectextensionspath = command.Option("--msbuildprojectextensionspath <PATH>", Resources.ProjectExtensionsDescription);
}
}
}

Просмотреть файл

@ -0,0 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo(
"dotnet-ef.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

379
src/dotnet-ef/Properties/Resources.Designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,379 @@
// <auto-generated />
using System.Reflection;
using System.Resources;
using JetBrains.Annotations;
namespace Microsoft.EntityFrameworkCore.Tools.Properties
{
/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
internal static class Resources
{
private static readonly ResourceManager _resourceManager
= new ResourceManager("Microsoft.EntityFrameworkCore.Tools.Properties.Resources", typeof(Resources).GetTypeInfo().Assembly);
/// <summary>
/// Build failed.
/// </summary>
public static string BuildFailed
=> GetString("BuildFailed");
/// <summary>
/// The configuration to use.
/// </summary>
public static string ConfigurationDescription
=> GetString("ConfigurationDescription");
/// <summary>
/// The connection string to the database.
/// </summary>
public static string ConnectionDescription
=> GetString("ConnectionDescription");
/// <summary>
/// The DbContext to use.
/// </summary>
public static string ContextDescription
=> GetString("ContextDescription");
/// <summary>
/// The name of the DbContext.
/// </summary>
public static string ContextNameDescription
=> GetString("ContextNameDescription");
/// <summary>
/// Use attributes to configure the model (where possible). If omitted, only the fluent API is used.
/// </summary>
public static string DataAnnotationsDescription
=> GetString("DataAnnotationsDescription");
/// <summary>
/// Commands to manage the database.
/// </summary>
public static string DatabaseDescription
=> GetString("DatabaseDescription");
/// <summary>
/// Drops the database.
/// </summary>
public static string DatabaseDropDescription
=> GetString("DatabaseDropDescription");
/// <summary>
/// Show which database would be dropped, but don't drop it.
/// </summary>
public static string DatabaseDropDryRunDescription
=> GetString("DatabaseDropDryRunDescription");
/// <summary>
/// Don't confirm.
/// </summary>
public static string DatabaseDropForceDescription
=> GetString("DatabaseDropForceDescription");
/// <summary>
/// Updates the database to a specified migration.
/// </summary>
public static string DatabaseUpdateDescription
=> GetString("DatabaseUpdateDescription");
/// <summary>
/// Commands to manage DbContext types.
/// </summary>
public static string DbContextDescription
=> GetString("DbContextDescription");
/// <summary>
/// Gets information about a DbContext type.
/// </summary>
public static string DbContextInfoDescription
=> GetString("DbContextInfoDescription");
/// <summary>
/// Lists available DbContext types.
/// </summary>
public static string DbContextListDescription
=> GetString("DbContextListDescription");
/// <summary>
/// Scaffolds a DbContext and entity types for a database.
/// </summary>
public static string DbContextScaffoldDescription
=> GetString("DbContextScaffoldDescription");
/// <summary>
/// Overwrite existing files.
/// </summary>
public static string DbContextScaffoldForceDescription
=> GetString("DbContextScaffoldForceDescription");
/// <summary>
/// Entity Framework Core .NET Command Line Tools
/// </summary>
public static string DotnetEfFullName
=> GetString("DotnetEfFullName");
/// <summary>
/// Entity Framework Core Command Line Tools
/// </summary>
public static string EFFullName
=> GetString("EFFullName");
/// <summary>
/// The environment to use. Defaults to "Development".
/// </summary>
public static string EnvironmentDescription
=> GetString("EnvironmentDescription");
/// <summary>
/// The target framework.
/// </summary>
public static string FrameworkDescription
=> GetString("FrameworkDescription");
/// <summary>
/// Unable to retrieve project metadata. Ensure it's an MSBuild-based .NET Core project. If you're using custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option.
/// </summary>
public static string GetMetadataFailed
=> GetString("GetMetadataFailed");
/// <summary>
/// Generate a script that can be used on a database at any migration.
/// </summary>
public static string IdempotentDescription
=> GetString("IdempotentDescription");
/// <summary>
/// Show JSON output.
/// </summary>
public static string JsonDescription
=> GetString("JsonDescription");
/// <summary>
/// The target migration. If '0', all migrations will be reverted. Defaults to the last migration.
/// </summary>
public static string MigrationDescription
=> GetString("MigrationDescription");
/// <summary>
/// The starting migration. Defaults to '0' (the initial database).
/// </summary>
public static string MigrationFromDescription
=> GetString("MigrationFromDescription");
/// <summary>
/// The name of the migration.
/// </summary>
public static string MigrationNameDescription
=> GetString("MigrationNameDescription");
/// <summary>
/// Adds a new migration.
/// </summary>
public static string MigrationsAddDescription
=> GetString("MigrationsAddDescription");
/// <summary>
/// Commands to manage migrations.
/// </summary>
public static string MigrationsDescription
=> GetString("MigrationsDescription");
/// <summary>
/// Lists available migrations.
/// </summary>
public static string MigrationsListDescription
=> GetString("MigrationsListDescription");
/// <summary>
/// The directory (and sub-namespace) to use. Paths are relative to the project directory. Defaults to "Migrations".
/// </summary>
public static string MigrationsOutputDirDescription
=> GetString("MigrationsOutputDirDescription");
/// <summary>
/// Removes the last migration.
/// </summary>
public static string MigrationsRemoveDescription
=> GetString("MigrationsRemoveDescription");
/// <summary>
/// Don't check to see if the migration has been applied to the database.
/// </summary>
public static string MigrationsRemoveForceDescription
=> GetString("MigrationsRemoveForceDescription");
/// <summary>
/// Generates a SQL script from migrations.
/// </summary>
public static string MigrationsScriptDescription
=> GetString("MigrationsScriptDescription");
/// <summary>
/// The ending migration. Defaults to the last migration.
/// </summary>
public static string MigrationToDescription
=> GetString("MigrationToDescription");
/// <summary>
/// More than one project was found in the current working directory. Use the --project option.
/// </summary>
public static string MultipleProjects
=> GetString("MultipleProjects");
/// <summary>
/// More than one project was found in directory '{projectDir}'. Specify one using its file name.
/// </summary>
public static string MultipleProjectsInDirectory([CanBeNull] object projectDir)
=> string.Format(
GetString("MultipleProjectsInDirectory", nameof(projectDir)),
projectDir);
/// <summary>
/// More than one project was found in the current working directory. Use the --startup-project option.
/// </summary>
public static string MultipleStartupProjects
=> GetString("MultipleStartupProjects");
/// <summary>
/// Startup project '{startupProject}' targets framework '.NETStandard'. This framework is not intended for execution and may fail to resolve runtime dependencies. If so, specify a different project using the --startup-project option and try again.
/// </summary>
public static string NETStandardStartupProject([CanBeNull] object startupProject)
=> string.Format(
GetString("NETStandardStartupProject", nameof(startupProject)),
startupProject);
/// <summary>
/// Don't colorize output.
/// </summary>
public static string NoColorDescription
=> GetString("NoColorDescription");
/// <summary>
/// No project was found. Change the current working directory or use the --project option.
/// </summary>
public static string NoProject
=> GetString("NoProject");
/// <summary>
/// No project was found in directory '{projectDir}'.
/// </summary>
public static string NoProjectInDirectory([CanBeNull] object projectDir)
=> string.Format(
GetString("NoProjectInDirectory", nameof(projectDir)),
projectDir);
/// <summary>
/// No project was found. Change the current working directory or use the --startup-project option.
/// </summary>
public static string NoStartupProject
=> GetString("NoStartupProject");
/// <summary>
/// The file to write the result to.
/// </summary>
public static string OutputDescription
=> GetString("OutputDescription");
/// <summary>
/// The directory to put files in. Paths are relative to the project directory.
/// </summary>
public static string OutputDirDescription
=> GetString("OutputDirDescription");
/// <summary>
/// Prefix output with level.
/// </summary>
public static string PrefixDescription
=> GetString("PrefixDescription");
/// <summary>
/// The project to use.
/// </summary>
public static string ProjectDescription
=> GetString("ProjectDescription");
/// <summary>
/// The MSBuild project extensions path. Defaults to "obj".
/// </summary>
public static string ProjectExtensionsDescription
=> GetString("ProjectExtensionsDescription");
/// <summary>
/// The provider to use. (E.g. Microsoft.EntityFrameworkCore.SqlServer)
/// </summary>
public static string ProviderDescription
=> GetString("ProviderDescription");
/// <summary>
/// The schemas of tables to generate entity types for.
/// </summary>
public static string SchemasDescription
=> GetString("SchemasDescription");
/// <summary>
/// The startup project to use.
/// </summary>
public static string StartupProjectDescription
=> GetString("StartupProjectDescription");
/// <summary>
/// The tables to generate entity types for.
/// </summary>
public static string TablesDescription
=> GetString("TablesDescription");
/// <summary>
/// Startup project '{startupProject}' targets framework '{targetFramework}'. The Entity Framework Core .NET Command Line Tools don't support this framework.
/// </summary>
public static string UnsupportedFramework([CanBeNull] object startupProject, [CanBeNull] object targetFramework)
=> string.Format(
GetString("UnsupportedFramework", nameof(startupProject), nameof(targetFramework)),
startupProject, targetFramework);
/// <summary>
/// Using project '{project}'.
/// </summary>
public static string UsingProject([CanBeNull] object project)
=> string.Format(
GetString("UsingProject", nameof(project)),
project);
/// <summary>
/// Using startup project '{startupProject}'.
/// </summary>
public static string UsingStartupProject([CanBeNull] object startupProject)
=> string.Format(
GetString("UsingStartupProject", nameof(startupProject)),
startupProject);
/// <summary>
/// Show verbose output.
/// </summary>
public static string VerboseDescription
=> GetString("VerboseDescription");
/// <summary>
/// Writing '{file}'...
/// </summary>
public static string WritingFile([CanBeNull] object file)
=> string.Format(
GetString("WritingFile", nameof(file)),
file);
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
for (var i = 0; i < formatterNames.Length; i++)
{
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
}
return value;
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<#
Session["ResourceFile"] = "Resources.resx";
Session["AccessModifier"] = "internal";
#>
<#@ include file="..\..\..\tools\Resources.tt" #>

Просмотреть файл

@ -0,0 +1,288 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="BuildFailed" xml:space="preserve">
<value>Build failed.</value>
</data>
<data name="ConfigurationDescription" xml:space="preserve">
<value>The configuration to use.</value>
</data>
<data name="ConnectionDescription" xml:space="preserve">
<value>The connection string to the database.</value>
</data>
<data name="ContextDescription" xml:space="preserve">
<value>The DbContext to use.</value>
</data>
<data name="ContextNameDescription" xml:space="preserve">
<value>The name of the DbContext.</value>
</data>
<data name="DataAnnotationsDescription" xml:space="preserve">
<value>Use attributes to configure the model (where possible). If omitted, only the fluent API is used.</value>
</data>
<data name="DatabaseDescription" xml:space="preserve">
<value>Commands to manage the database.</value>
</data>
<data name="DatabaseDropDescription" xml:space="preserve">
<value>Drops the database.</value>
</data>
<data name="DatabaseDropDryRunDescription" xml:space="preserve">
<value>Show which database would be dropped, but don't drop it.</value>
</data>
<data name="DatabaseDropForceDescription" xml:space="preserve">
<value>Don't confirm.</value>
</data>
<data name="DatabaseUpdateDescription" xml:space="preserve">
<value>Updates the database to a specified migration.</value>
</data>
<data name="DbContextDescription" xml:space="preserve">
<value>Commands to manage DbContext types.</value>
</data>
<data name="DbContextInfoDescription" xml:space="preserve">
<value>Gets information about a DbContext type.</value>
</data>
<data name="DbContextListDescription" xml:space="preserve">
<value>Lists available DbContext types.</value>
</data>
<data name="DbContextScaffoldDescription" xml:space="preserve">
<value>Scaffolds a DbContext and entity types for a database.</value>
</data>
<data name="DbContextScaffoldForceDescription" xml:space="preserve">
<value>Overwrite existing files.</value>
</data>
<data name="DotnetEfFullName" xml:space="preserve">
<value>Entity Framework Core .NET Command Line Tools</value>
</data>
<data name="EFFullName" xml:space="preserve">
<value>Entity Framework Core Command Line Tools</value>
</data>
<data name="EnvironmentDescription" xml:space="preserve">
<value>The environment to use. Defaults to "Development".</value>
</data>
<data name="FrameworkDescription" xml:space="preserve">
<value>The target framework.</value>
</data>
<data name="GetMetadataFailed" xml:space="preserve">
<value>Unable to retrieve project metadata. Ensure it's an MSBuild-based .NET Core project. If you're using custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option.</value>
</data>
<data name="IdempotentDescription" xml:space="preserve">
<value>Generate a script that can be used on a database at any migration.</value>
</data>
<data name="JsonDescription" xml:space="preserve">
<value>Show JSON output.</value>
</data>
<data name="MigrationDescription" xml:space="preserve">
<value>The target migration. If '0', all migrations will be reverted. Defaults to the last migration.</value>
</data>
<data name="MigrationFromDescription" xml:space="preserve">
<value>The starting migration. Defaults to '0' (the initial database).</value>
</data>
<data name="MigrationNameDescription" xml:space="preserve">
<value>The name of the migration.</value>
</data>
<data name="MigrationsAddDescription" xml:space="preserve">
<value>Adds a new migration.</value>
</data>
<data name="MigrationsDescription" xml:space="preserve">
<value>Commands to manage migrations.</value>
</data>
<data name="MigrationsListDescription" xml:space="preserve">
<value>Lists available migrations.</value>
</data>
<data name="MigrationsOutputDirDescription" xml:space="preserve">
<value>The directory (and sub-namespace) to use. Paths are relative to the project directory. Defaults to "Migrations".</value>
</data>
<data name="MigrationsRemoveDescription" xml:space="preserve">
<value>Removes the last migration.</value>
</data>
<data name="MigrationsRemoveForceDescription" xml:space="preserve">
<value>Don't check to see if the migration has been applied to the database.</value>
</data>
<data name="MigrationsScriptDescription" xml:space="preserve">
<value>Generates a SQL script from migrations.</value>
</data>
<data name="MigrationToDescription" xml:space="preserve">
<value>The ending migration. Defaults to the last migration.</value>
</data>
<data name="MultipleProjects" xml:space="preserve">
<value>More than one project was found in the current working directory. Use the --project option.</value>
</data>
<data name="MultipleProjectsInDirectory" xml:space="preserve">
<value>More than one project was found in directory '{projectDir}'. Specify one using its file name.</value>
</data>
<data name="MultipleStartupProjects" xml:space="preserve">
<value>More than one project was found in the current working directory. Use the --startup-project option.</value>
</data>
<data name="NETStandardStartupProject" xml:space="preserve">
<value>Startup project '{startupProject}' targets framework '.NETStandard'. This framework is not intended for execution and may fail to resolve runtime dependencies. If so, specify a different project using the --startup-project option and try again.</value>
</data>
<data name="NoColorDescription" xml:space="preserve">
<value>Don't colorize output.</value>
</data>
<data name="NoProject" xml:space="preserve">
<value>No project was found. Change the current working directory or use the --project option.</value>
</data>
<data name="NoProjectInDirectory" xml:space="preserve">
<value>No project was found in directory '{projectDir}'.</value>
</data>
<data name="NoStartupProject" xml:space="preserve">
<value>No project was found. Change the current working directory or use the --startup-project option.</value>
</data>
<data name="OutputDescription" xml:space="preserve">
<value>The file to write the result to.</value>
</data>
<data name="OutputDirDescription" xml:space="preserve">
<value>The directory to put files in. Paths are relative to the project directory.</value>
</data>
<data name="PrefixDescription" xml:space="preserve">
<value>Prefix output with level.</value>
</data>
<data name="ProjectDescription" xml:space="preserve">
<value>The project to use.</value>
</data>
<data name="ProjectExtensionsDescription" xml:space="preserve">
<value>The MSBuild project extensions path. Defaults to "obj".</value>
</data>
<data name="ProviderDescription" xml:space="preserve">
<value>The provider to use. (E.g. Microsoft.EntityFrameworkCore.SqlServer)</value>
</data>
<data name="SchemasDescription" xml:space="preserve">
<value>The schemas of tables to generate entity types for.</value>
</data>
<data name="StartupProjectDescription" xml:space="preserve">
<value>The startup project to use.</value>
</data>
<data name="TablesDescription" xml:space="preserve">
<value>The tables to generate entity types for.</value>
</data>
<data name="UnsupportedFramework" xml:space="preserve">
<value>Startup project '{startupProject}' targets framework '{targetFramework}'. The Entity Framework Core .NET Command Line Tools don't support this framework.</value>
</data>
<data name="UsingProject" xml:space="preserve">
<value>Using project '{project}'.</value>
</data>
<data name="UsingStartupProject" xml:space="preserve">
<value>Using startup project '{startupProject}'.</value>
</data>
<data name="VerboseDescription" xml:space="preserve">
<value>Show verbose output.</value>
</data>
<data name="WritingFile" xml:space="preserve">
<value>Writing '{file}'...</value>
</data>
</root>

Просмотреть файл

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="GetEFProjectMetadata" Condition="">
<MSBuild Condition=" '$(TargetFramework)' == '' "
Projects="$(MSBuildProjectFile)"
Targets="GetEFProjectMetadata"
Properties="TargetFramework=$(TargetFrameworks.Split(';')[0]);EFProjectMetadataFile=$(EFProjectMetadataFile)" />
<ItemGroup Condition=" '$(TargetFramework)' != '' ">
<EFProjectMetadata Include="AssemblyName: $(AssemblyName)" />
<EFProjectMetadata Include="OutputPath: $(OutputPath)" />
<EFProjectMetadata Include="Platform: $(Platform)" />
<EFProjectMetadata Include="PlatformTarget: $(PlatformTarget)" />
<EFProjectMetadata Include="ProjectAssetsFile: $(ProjectAssetsFile)" />
<EFProjectMetadata Include="ProjectDir: $(ProjectDir)" />
<EFProjectMetadata Include="RootNamespace: $(RootNamespace)" />
<EFProjectMetadata Include="TargetFileName: $(TargetFileName)" />
<EFProjectMetadata Include="TargetFrameworkMoniker: $(TargetFrameworkMoniker)" />
</ItemGroup>
<WriteLinesToFile Condition=" '$(TargetFramework)' != '' "
File="$(EFProjectMetadataFile)"
Lines="@(EFProjectMetadata)" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,260 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Versioning;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Commands;
using Microsoft.EntityFrameworkCore.Tools.Properties;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using EFCommand = Microsoft.EntityFrameworkCore.Tools.Commands.RootCommand;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal class RootCommand : CommandBase
{
private CommandLineApplication _command;
private CommandOption _project;
private CommandOption _startupProject;
private CommandOption _framework;
private CommandOption _configuration;
private CommandOption _msbuildprojectextensionspath;
private CommandOption _help;
private IList<string> _args;
public override void Configure(CommandLineApplication command)
{
command.FullName = Resources.DotnetEfFullName;
var options = new ProjectOptions();
options.Configure(command);
_project = options.Project;
_startupProject = options.StartupProject;
_framework = options.Framework;
_configuration = options.Configuration;
_msbuildprojectextensionspath = options.MSBuildProjectExtensionsPath;
command.VersionOption("--version", GetVersion);
_help = command.Option("-h|--help", description: null);
_args = command.RemainingArguments;
base.Configure(command);
_command = command;
}
protected override int Execute()
{
var commands = _args.TakeWhile(a => a[0] != '-').ToList();
if (_help.HasValue() || ShouldHelp(commands))
{
return ShowHelp(_help.HasValue(), commands);
}
var projectFile = FindProjects(
_project.Value(),
Resources.NoProject,
Resources.MultipleProjects);
Reporter.WriteVerbose(Resources.UsingProject(projectFile));
var starupProjectFile = FindProjects(
_startupProject.Value(),
Resources.NoStartupProject,
Resources.MultipleStartupProjects);
Reporter.WriteVerbose(Resources.UsingStartupProject(starupProjectFile));
var project = Project.FromFile(projectFile, _msbuildprojectextensionspath.Value());
var startupProject = Project.FromFile(
starupProjectFile,
_msbuildprojectextensionspath.Value(),
_framework.Value(),
_configuration.Value());
startupProject.Build();
string executable;
var args = new List<string>();
var toolsPath = Path.GetFullPath(
Path.Combine(
Path.GetDirectoryName(typeof(Program).GetTypeInfo().Assembly.Location),
"..",
"..",
"tools"));
var targetDir = Path.GetFullPath(Path.Combine(startupProject.ProjectDir, startupProject.OutputPath));
var targetPath = Path.Combine(targetDir, project.TargetFileName);
var startupTargetPath = Path.Combine(targetDir, startupProject.TargetFileName);
var depsFile = Path.Combine(
targetDir,
startupProject.AssemblyName + ".deps.json");
var runtimeConfig = Path.Combine(
targetDir,
startupProject.AssemblyName + ".runtimeconfig.json");
var projectAssetsFile = startupProject.ProjectAssetsFile;
var targetFramework = new FrameworkName(startupProject.TargetFrameworkMoniker);
if (targetFramework.Identifier == ".NETFramework")
{
executable = Path.Combine(
toolsPath,
"net451",
startupProject.PlatformTarget == "x86"
? "ef.x86.exe"
: "ef.exe");
}
else if (targetFramework.Identifier == ".NETCoreApp"
|| targetFramework.Identifier == ".NETStandard")
{
if (targetFramework.Identifier == ".NETStandard")
{
Reporter.WriteWarning(Resources.NETStandardStartupProject(startupProject.ProjectName));
}
executable = "dotnet";
args.Add("exec");
args.Add("--depsfile");
args.Add(depsFile);
if (!string.IsNullOrEmpty(projectAssetsFile))
{
using (var reader = new JsonTextReader(File.OpenText(projectAssetsFile)))
{
var projectAssets = JObject.ReadFrom(reader);
var packageFolders = projectAssets["packageFolders"].Children<JProperty>().Select(p => p.Name);
foreach (var packageFolder in packageFolders)
{
args.Add("--additionalprobingpath");
args.Add(packageFolder.TrimEnd(Path.DirectorySeparatorChar));
}
}
}
if (File.Exists(runtimeConfig))
{
args.Add("--runtimeconfig");
args.Add(runtimeConfig);
}
args.Add(Path.Combine(toolsPath, "netcoreapp1.0", "ef.dll"));
}
else
{
throw new CommandException(
Resources.UnsupportedFramework(startupProject.ProjectName, targetFramework.Identifier));
}
args.AddRange(_args);
args.Add("--assembly");
args.Add(targetPath);
args.Add("--startup-assembly");
args.Add(startupTargetPath);
args.Add("--project-dir");
args.Add(project.ProjectDir);
args.Add("--content-root");
args.Add(startupProject.ProjectDir);
args.Add("--data-dir");
args.Add(targetDir);
if (Reporter.IsVerbose)
{
args.Add("--verbose");
}
if (Reporter.NoColor)
{
args.Add("--no-color");
}
if (Reporter.PrefixOutput)
{
args.Add("--prefix-output");
}
if (project.RootNamespace.Length != 0)
{
args.Add("--root-namespace");
args.Add(project.RootNamespace);
}
return Exe.Run(executable, args);
}
private static string FindProjects(
string path,
string errorWhenNoProject,
string errorWhenMultipleProjects)
{
var specified = true;
if (path == null)
{
specified = false;
path = Directory.GetCurrentDirectory();
}
else if (!Directory.Exists(path)) // It's not a directory
{
return path;
}
var projectFiles = Directory.EnumerateFiles(path, "*.*proj", SearchOption.TopDirectoryOnly)
.Where(f => !string.Equals(Path.GetExtension(f), ".xproj", StringComparison.OrdinalIgnoreCase))
.Take(2).ToList();
if (projectFiles.Count == 0)
{
throw new CommandException(
specified
? Resources.NoProjectInDirectory(path)
: errorWhenNoProject);
}
if (projectFiles.Count != 1)
{
throw new CommandException(
specified
? Resources.MultipleProjectsInDirectory(path)
: errorWhenMultipleProjects);
}
return projectFiles[0];
}
private static string GetVersion()
=> typeof(RootCommand).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
.InformationalVersion;
private static bool ShouldHelp(IReadOnlyList<string> commands)
=> commands.Count == 0
|| (commands.Count == 1
&& (commands[0] == "database"
|| commands[0] == "dbcontext"
|| commands[0] == "migrations"));
private int ShowHelp(bool help, IEnumerable<string> commands)
{
var app = new CommandLineApplication
{
Name = _command.Name
};
new EFCommand().Configure(app);
app.FullName = _command.FullName;
var args = new List<string>(commands);
if (help)
{
args.Add("--help");
}
return app.Execute(args.ToArray());
}
}
}

Просмотреть файл

@ -0,0 +1,62 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<Description>Entity Framework Core .NET Command Line Tools</Description>
<TargetFramework>netcoreapp1.0</TargetFramework>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<RootNamespace>Microsoft.EntityFrameworkCore.Tools</RootNamespace>
<RuntimeFrameworkVersion>1.0.0</RuntimeFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\ef\CommandLineUtils\*.cs" />
<Compile Include="..\ef\Commands\CommandBase.cs" />
<Compile Include="..\ef\Commands\ContextCommandBase.cs" />
<Compile Include="..\ef\Commands\DatabaseCommand.cs" />
<Compile Include="..\ef\Commands\DbContextCommand.cs" />
<Compile Include="..\ef\Commands\EFCommandBase.cs" />
<Compile Include="..\ef\Commands\EnvironmentCommandBase.cs" />
<Compile Include="..\ef\Commands\HelpCommandBase.cs" />
<Compile Include="..\ef\Commands\MigrationsCommand.cs" />
<Compile Include="..\ef\Commands\RootCommand.cs" />
<Compile Include="..\ef\AnsiConsole.cs" />
<Compile Include="..\ef\AnsiConstants.cs" />
<Compile Include="..\ef\AnsiTextWriter.cs" />
<Compile Include="..\ef\CommandException.cs" />
<Compile Include="..\ef\Json.cs" />
<Compile Include="..\ef\Reporter.cs" />
<Compile Include="..\ef\Commands\**\*.Configure.cs" />
<Compile Include="..\Shared\CodeAnnotations.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\EntityFrameworkCore.targets" />
</ItemGroup>
<ItemGroup>
<None Update="Properties\Resources.Designer.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.Designer.tt</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
</Project>

15
src/ef/AnsiConsole.cs Normal file
Просмотреть файл

@ -0,0 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal class AnsiConsole
{
public static readonly AnsiTextWriter _out = new AnsiTextWriter(Console.Out);
public static void WriteLine(string text)
=> _out.WriteLine(text);
}
}

20
src/ef/AnsiConstants.cs Normal file
Просмотреть файл

@ -0,0 +1,20 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.EntityFrameworkCore.Tools
{
internal static class AnsiConstants
{
public const string Reset = "\x1b[22m\x1b[39m";
public const string Bold = "\x1b[1m";
public const string Dark = "\x1b[22m";
public const string Black = "\x1b[30m";
public const string Red = "\x1b[31m";
public const string Green = "\x1b[32m";
public const string Yellow = "\x1b[33m";
public const string Blue = "\x1b[34m";
public const string Magenta = "\x1b[35m";
public const string Cyan = "\x1b[36m";
public const string Gray = "\x1b[37m";
}
}

134
src/ef/AnsiTextWriter.cs Normal file
Просмотреть файл

@ -0,0 +1,134 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal class AnsiTextWriter
{
private readonly TextWriter _writer;
public AnsiTextWriter(TextWriter writer)
{
_writer = writer;
}
public void WriteLine(string text)
{
Interpret(text);
_writer.Write(Environment.NewLine);
}
private void Interpret(string value)
{
var matches = Regex.Matches(value, "\x1b\\[([0-9]+)?m");
var start = 0;
foreach (Match match in matches)
{
var length = match.Index - start;
if (length != 0)
{
_writer.Write(value.Substring(start, length));
}
Apply(match.Groups[1].Value);
start = match.Index + match.Length;
}
if (start != value.Length)
{
_writer.Write(value.Substring(start));
}
}
private static void Apply(string parameter)
{
switch (parameter)
{
case "1":
ApplyBold();
break;
case "22":
ResetBold();
break;
case "30":
ApplyColor(ConsoleColor.Black);
break;
case "31":
ApplyColor(ConsoleColor.DarkRed);
break;
case "32":
ApplyColor(ConsoleColor.DarkGreen);
break;
case "33":
ApplyColor(ConsoleColor.DarkYellow);
break;
case "34":
ApplyColor(ConsoleColor.DarkBlue);
break;
case "35":
ApplyColor(ConsoleColor.DarkMagenta);
break;
case "36":
ApplyColor(ConsoleColor.DarkCyan);
break;
case "37":
ApplyColor(ConsoleColor.Gray);
break;
case "39":
ResetColor();
break;
default:
Debug.Fail("Unsupported parameter: " + parameter);
break;
}
}
private static void ApplyBold()
=> Console.ForegroundColor = (ConsoleColor)((int)Console.ForegroundColor | 8);
private static void ResetBold()
=> Console.ForegroundColor = (ConsoleColor)((int)Console.ForegroundColor & 7);
private static void ApplyColor(ConsoleColor color)
{
var wasBold = ((int)Console.ForegroundColor & 8) != 0;
Console.ForegroundColor = color;
if (wasBold)
{
ApplyBold();
}
}
private static void ResetColor()
{
var wasBold = ((int)Console.ForegroundColor & 8) != 0;
Console.ResetColor();
if (wasBold)
{
ApplyBold();
}
}
}
}

Просмотреть файл

@ -0,0 +1,101 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#if NET451
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal class AppDomainOperationExecutor : OperationExecutorBase
{
private readonly object _executor;
private readonly AppDomain _domain;
private bool _disposed;
public AppDomainOperationExecutor(
string assembly,
string startupAssembly,
string projectDir,
string contentRootPath,
string dataDirectory,
string rootNamespace,
string environment)
: base(assembly, startupAssembly, projectDir, contentRootPath, dataDirectory, rootNamespace, environment)
{
var info = new AppDomainSetup { ApplicationBase = AppBasePath };
var configurationFile = (startupAssembly ?? assembly) + ".config";
if (File.Exists(configurationFile))
{
Reporter.WriteVerbose(Resources.UsingConfigurationFile(configurationFile));
info.ConfigurationFile = configurationFile;
}
_domain = AppDomain.CreateDomain("EntityFrameworkCore.DesignDomain", null, info);
if (dataDirectory != null)
{
_domain.SetData("DataDirectory", dataDirectory);
}
var reportHandler = new OperationReportHandler(
Reporter.WriteError,
Reporter.WriteWarning,
Reporter.WriteInformation,
Reporter.WriteVerbose);
_executor = _domain.CreateInstanceAndUnwrap(
DesignAssemblyName,
ExecutorTypeName,
false,
BindingFlags.Default,
null,
new object[]
{
reportHandler,
new Hashtable
{
{ "targetName", AssemblyFileName },
{ "startupTargetName", StartupAssemblyFileName },
{ "projectDir", ProjectDirectory },
{ "contentRootPath", ContentRootPath },
{ "rootNamespace", RootNamespace },
{ "environment", EnvironmentName }
}
},
null,
null);
}
protected override object CreateResultHandler()
=> new OperationResultHandler();
protected override void Execute(string operationName, object resultHandler, IDictionary arguments)
=> _domain.CreateInstance(
DesignAssemblyName,
ExecutorTypeName + "+" + operationName,
false,
BindingFlags.Default,
null,
new[] { _executor, resultHandler, arguments },
null,
null);
public override void Dispose()
{
if (!_disposed)
{
_disposed = true;
AppDomain.Unload(_domain);
}
}
}
}
#endif

Просмотреть файл

@ -0,0 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal class CommandException : Exception
{
public CommandException(string message)
: base(message)
{
}
}
}

Просмотреть файл

@ -0,0 +1,28 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class CommandArgument
{
public CommandArgument()
{
Values = new List<string>();
}
public string Name { get; set; }
public string Description { get; set; }
public List<string> Values { get; private set; }
public bool MultipleValues { get; set; }
public string Value
{
get
{
return Values.FirstOrDefault();
}
}
}
}

Просмотреть файл

@ -0,0 +1,636 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class CommandLineApplication
{
private enum ParseOptionResult
{
Succeeded,
ShowHelp,
ShowVersion,
UnexpectedArgs,
}
// Indicates whether the parser should throw an exception when it runs into an unexpected argument.
// If this field is set to false, the parser will stop parsing when it sees an unexpected argument, and all
// remaining arguments, including the first unexpected argument, will be stored in RemainingArguments property.
private readonly bool _throwOnUnexpectedArg;
public CommandLineApplication(bool throwOnUnexpectedArg = true)
{
_throwOnUnexpectedArg = throwOnUnexpectedArg;
Options = new List<CommandOption>();
Arguments = new List<CommandArgument>();
Commands = new List<CommandLineApplication>();
RemainingArguments = new List<string>();
Invoke = () => 0;
}
public CommandLineApplication Parent { get; set; }
public string Name { get; set; }
public string FullName { get; set; }
public string Syntax { get; set; }
public string Description { get; set; }
public List<CommandOption> Options { get; private set; }
public CommandOption OptionHelp { get; private set; }
public CommandOption OptionVersion { get; private set; }
public List<CommandArgument> Arguments { get; private set; }
public List<string> RemainingArguments { get; private set; }
public bool IsShowingInformation { get; protected set; } // Is showing help or version?
public Func<int> Invoke { get; set; }
public Func<string> LongVersionGetter { get; set; }
public Func<string> ShortVersionGetter { get; set; }
public List<CommandLineApplication> Commands { get; private set; }
public bool HandleResponseFiles { get; set; }
public bool AllowArgumentSeparator { get; set; }
public bool HandleRemainingArguments { get; set; }
public string ArgumentSeparatorHelpText { get; set; }
public CommandLineApplication Command(string name, bool throwOnUnexpectedArg = true)
{
return Command(name, _ => { }, throwOnUnexpectedArg);
}
public CommandLineApplication Command(string name, Action<CommandLineApplication> configuration,
bool throwOnUnexpectedArg = true)
{
var command = new CommandLineApplication(throwOnUnexpectedArg) { Name = name, Parent = this };
Commands.Add(command);
configuration(command);
return command;
}
public CommandOption Option(string template, string description, CommandOptionType optionType)
{
return Option(template, description, optionType, _ => { });
}
public CommandOption Option(string template, string description, CommandOptionType optionType, Action<CommandOption> configuration)
{
var option = new CommandOption(template, optionType) { Description = description };
Options.Add(option);
configuration(option);
return option;
}
public CommandArgument Argument(string name, string description, bool multipleValues = false)
{
return Argument(name, description, _ => { }, multipleValues);
}
public CommandArgument Argument(string name, string description, Action<CommandArgument> configuration, bool multipleValues = false)
{
var lastArg = Arguments.LastOrDefault();
if (lastArg != null && lastArg.MultipleValues)
{
var message = string.Format("The last argument '{0}' accepts multiple values. No more argument can be added.",
lastArg.Name);
throw new InvalidOperationException(message);
}
var argument = new CommandArgument { Name = name, Description = description, MultipleValues = multipleValues };
Arguments.Add(argument);
configuration(argument);
return argument;
}
public void OnExecute(Func<int> invoke)
{
Invoke = invoke;
}
public void OnExecute(Func<Task<int>> invoke)
{
Invoke = () => invoke().Result;
}
public int Execute(params string[] args)
{
CommandLineApplication command = this;
IEnumerator<CommandArgument> arguments = null;
if (HandleResponseFiles)
{
args = ExpandResponseFiles(args).ToArray();
}
for (var index = 0; index < args.Length; index++)
{
var arg = args[index];
bool isLongOption = arg.StartsWith("--");
if (isLongOption || arg.StartsWith("-"))
{
CommandOption option;
var result = ParseOption(isLongOption, command, args, ref index, out option);
if (result == ParseOptionResult.ShowHelp)
{
command.ShowHelp();
return 0;
}
else if (result == ParseOptionResult.ShowVersion)
{
command.ShowVersion();
return 0;
}
}
else
{
var subcommand = ParseSubCommand(arg, command);
if (subcommand != null)
{
command = subcommand;
}
else
{
if (arguments == null)
{
arguments = new CommandArgumentEnumerator(command.Arguments.GetEnumerator());
}
if (arguments.MoveNext())
{
arguments.Current.Values.Add(arg);
}
else
{
HandleUnexpectedArg(command, args, index, argTypeName: "command or argument");
}
}
}
}
return command.Invoke();
}
private ParseOptionResult ParseOption(
bool isLongOption,
CommandLineApplication command,
string[] args,
ref int index,
out CommandOption option)
{
option = null;
ParseOptionResult result = ParseOptionResult.Succeeded;
var arg = args[index];
int optionPrefixLength = isLongOption ? 2 : 1;
string[] optionComponents = arg.Substring(optionPrefixLength).Split(new[] { ':', '=' }, 2);
string optionName = optionComponents[0];
if (isLongOption)
{
option = command.Options.SingleOrDefault(
opt => string.Equals(opt.LongName, optionName, StringComparison.Ordinal));
}
else
{
option = command.Options.SingleOrDefault(
opt => string.Equals(opt.ShortName, optionName, StringComparison.Ordinal));
if (option == null)
{
option = command.Options.SingleOrDefault(
opt => string.Equals(opt.SymbolName, optionName, StringComparison.Ordinal));
}
}
if (option == null)
{
if (isLongOption && string.IsNullOrEmpty(optionName) &&
!command._throwOnUnexpectedArg && AllowArgumentSeparator)
{
// a stand-alone "--" is the argument separator, so skip it and
// handle the rest of the args as unexpected args
index++;
}
HandleUnexpectedArg(command, args, index, argTypeName: "option");
result = ParseOptionResult.UnexpectedArgs;
}
else if (command.OptionHelp == option)
{
result = ParseOptionResult.ShowHelp;
}
else if (command.OptionVersion == option)
{
result = ParseOptionResult.ShowVersion;
}
else
{
if (optionComponents.Length == 2)
{
if (!option.TryParse(optionComponents[1]))
{
command.ShowHint();
throw new CommandParsingException(command,
$"Unexpected value '{optionComponents[1]}' for option '{optionName}'");
}
}
else
{
if (option.OptionType == CommandOptionType.NoValue ||
option.OptionType == CommandOptionType.BoolValue)
{
// No value is needed for this option
option.TryParse(null);
}
else
{
index++;
arg = args[index];
if (!option.TryParse(arg))
{
command.ShowHint();
throw new CommandParsingException(command, $"Unexpected value '{arg}' for option '{optionName}'");
}
}
}
}
return result;
}
private CommandLineApplication ParseSubCommand(string arg, CommandLineApplication command)
{
foreach (var subcommand in command.Commands)
{
if (string.Equals(subcommand.Name, arg, StringComparison.OrdinalIgnoreCase))
{
return subcommand;
}
}
return null;
}
// Helper method that adds a help option
public CommandOption HelpOption(string template)
{
// Help option is special because we stop parsing once we see it
// So we store it separately for further use
OptionHelp = Option(template, "Show help information", CommandOptionType.NoValue);
return OptionHelp;
}
public CommandOption VersionOption(string template,
string shortFormVersion,
string longFormVersion = null)
{
if (longFormVersion == null)
{
return VersionOption(template, () => shortFormVersion);
}
else
{
return VersionOption(template, () => shortFormVersion, () => longFormVersion);
}
}
// Helper method that adds a version option
public CommandOption VersionOption(string template,
Func<string> shortFormVersionGetter,
Func<string> longFormVersionGetter = null)
{
// Version option is special because we stop parsing once we see it
// So we store it separately for further use
OptionVersion = Option(template, "Show version information", CommandOptionType.NoValue);
ShortVersionGetter = shortFormVersionGetter;
LongVersionGetter = longFormVersionGetter ?? shortFormVersionGetter;
return OptionVersion;
}
// Show short hint that reminds users to use help option
public void ShowHint()
{
if (OptionHelp != null)
{
Console.WriteLine(string.Format("Specify --{0} for a list of available options and commands.", OptionHelp.LongName));
}
}
// Show full help
public void ShowHelp(string commandName = null)
{
var headerBuilder = new StringBuilder("Usage:");
var usagePrefixLength = headerBuilder.Length;
for (var cmd = this; cmd != null; cmd = cmd.Parent)
{
cmd.IsShowingInformation = true;
if (cmd != this && cmd.Arguments.Any())
{
var args = string.Join(" ", cmd.Arguments.Select(arg => arg.Name));
headerBuilder.Insert(usagePrefixLength, string.Format(" {0} {1}", cmd.Name, args));
}
else
{
headerBuilder.Insert(usagePrefixLength, string.Format(" {0}", cmd.Name));
}
}
CommandLineApplication target;
if (commandName == null || string.Equals(Name, commandName, StringComparison.OrdinalIgnoreCase))
{
target = this;
}
else
{
target = Commands.SingleOrDefault(cmd => string.Equals(cmd.Name, commandName, StringComparison.OrdinalIgnoreCase));
if (target != null)
{
headerBuilder.AppendFormat(" {0}", commandName);
}
else
{
// The command name is invalid so don't try to show help for something that doesn't exist
target = this;
}
}
var optionsBuilder = new StringBuilder();
var commandsBuilder = new StringBuilder();
var argumentsBuilder = new StringBuilder();
var argumentSeparatorBuilder = new StringBuilder();
int maxArgLen = 0;
for (var cmd = target; cmd != null; cmd = cmd.Parent)
{
if (cmd.Arguments.Any())
{
if (cmd == target)
{
headerBuilder.Append(" [arguments]");
}
if (argumentsBuilder.Length == 0)
{
argumentsBuilder.AppendLine();
argumentsBuilder.AppendLine("Arguments:");
}
maxArgLen = Math.Max(maxArgLen, MaxArgumentLength(cmd.Arguments));
}
}
for (var cmd = target; cmd != null; cmd = cmd.Parent)
{
if (cmd.Arguments.Any())
{
var outputFormat = " {0}{1}";
foreach (var arg in cmd.Arguments)
{
argumentsBuilder.AppendFormat(
outputFormat,
arg.Name.PadRight(maxArgLen + 2),
arg.Description);
argumentsBuilder.AppendLine();
}
}
}
if (target.Options.Any())
{
headerBuilder.Append(" [options]");
optionsBuilder.AppendLine();
optionsBuilder.AppendLine("Options:");
var maxOptLen = MaxOptionTemplateLength(target.Options);
var outputFormat = string.Format(" {{0, -{0}}}{{1}}", maxOptLen + 2);
foreach (var opt in target.Options)
{
optionsBuilder.AppendFormat(outputFormat, opt.Template, opt.Description);
optionsBuilder.AppendLine();
}
}
if (target.Commands.Any())
{
headerBuilder.Append(" [command]");
commandsBuilder.AppendLine();
commandsBuilder.AppendLine("Commands:");
var maxCmdLen = MaxCommandLength(target.Commands);
var outputFormat = string.Format(" {{0, -{0}}}{{1}}", maxCmdLen + 2);
foreach (var cmd in target.Commands.OrderBy(c => c.Name))
{
commandsBuilder.AppendFormat(outputFormat, cmd.Name, cmd.Description);
commandsBuilder.AppendLine();
}
if (OptionHelp != null)
{
commandsBuilder.AppendLine();
commandsBuilder.AppendFormat("Use \"{0} [command] --help\" for more information about a command.", Name);
commandsBuilder.AppendLine();
}
}
if (target.AllowArgumentSeparator || target.HandleRemainingArguments)
{
if (target.AllowArgumentSeparator)
{
headerBuilder.Append(" [[--] <arg>...]]");
}
else
{
headerBuilder.Append(" [args]");
}
if (!string.IsNullOrEmpty(target.ArgumentSeparatorHelpText))
{
argumentSeparatorBuilder.AppendLine();
argumentSeparatorBuilder.AppendLine("Args:");
argumentSeparatorBuilder.AppendLine($" {target.ArgumentSeparatorHelpText}");
argumentSeparatorBuilder.AppendLine();
}
}
headerBuilder.AppendLine();
var nameAndVersion = new StringBuilder();
nameAndVersion.AppendLine(GetFullNameAndVersion());
nameAndVersion.AppendLine();
Console.Write("{0}{1}{2}{3}{4}{5}", nameAndVersion, headerBuilder, argumentsBuilder, optionsBuilder, commandsBuilder, argumentSeparatorBuilder);
}
public void ShowVersion()
{
for (var cmd = this; cmd != null; cmd = cmd.Parent)
{
cmd.IsShowingInformation = true;
}
Console.WriteLine(FullName);
Console.WriteLine(LongVersionGetter());
}
public string GetFullNameAndVersion()
{
return ShortVersionGetter == null ? FullName : string.Format("{0} {1}", FullName, ShortVersionGetter());
}
public void ShowRootCommandFullNameAndVersion()
{
var rootCmd = this;
while (rootCmd.Parent != null)
{
rootCmd = rootCmd.Parent;
}
Console.WriteLine(rootCmd.GetFullNameAndVersion());
Console.WriteLine();
}
private int MaxOptionTemplateLength(IEnumerable<CommandOption> options)
{
var maxLen = 0;
foreach (var opt in options)
{
maxLen = opt.Template.Length > maxLen ? opt.Template.Length : maxLen;
}
return maxLen;
}
private int MaxCommandLength(IEnumerable<CommandLineApplication> commands)
{
var maxLen = 0;
foreach (var cmd in commands)
{
maxLen = cmd.Name.Length > maxLen ? cmd.Name.Length : maxLen;
}
return maxLen;
}
private int MaxArgumentLength(IEnumerable<CommandArgument> arguments)
{
var maxLen = 0;
foreach (var arg in arguments)
{
maxLen = arg.Name.Length > maxLen ? arg.Name.Length : maxLen;
}
return maxLen;
}
private void HandleUnexpectedArg(CommandLineApplication command, string[] args, int index, string argTypeName)
{
if (command._throwOnUnexpectedArg)
{
command.ShowHint();
throw new CommandParsingException(command, $"Unrecognized {argTypeName} '{args[index]}'");
}
else
{
command.RemainingArguments.Add(args[index]);
}
}
private IEnumerable<string> ExpandResponseFiles(IEnumerable<string> args)
{
foreach (var arg in args)
{
if (!arg.StartsWith("@", StringComparison.Ordinal))
{
yield return arg;
}
else
{
var fileName = arg.Substring(1);
var responseFileArguments = ParseResponseFile(fileName);
// ParseResponseFile can suppress expanding this response file by
// returning null. In that case, we'll treat the response
// file token as a regular argument.
if (responseFileArguments == null)
{
yield return arg;
}
else
{
foreach (var responseFileArgument in responseFileArguments)
yield return responseFileArgument.Trim();
}
}
}
}
private IEnumerable<string> ParseResponseFile(string fileName)
{
if (!HandleResponseFiles)
return null;
if (!File.Exists(fileName))
{
throw new InvalidOperationException($"Response file '{fileName}' doesn't exist.");
}
return File.ReadLines(fileName);
}
private class CommandArgumentEnumerator : IEnumerator<CommandArgument>
{
private readonly IEnumerator<CommandArgument> _enumerator;
public CommandArgumentEnumerator(IEnumerator<CommandArgument> enumerator)
{
_enumerator = enumerator;
}
public CommandArgument Current
{
get
{
return _enumerator.Current;
}
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public void Dispose()
{
_enumerator.Dispose();
}
public bool MoveNext()
{
if (Current == null || !Current.MultipleValues)
{
return _enumerator.MoveNext();
}
// If current argument allows multiple values, we don't move forward and
// all later values will be added to current CommandArgument.Values
return true;
}
public void Reset()
{
_enumerator.Reset();
}
}
}
}

Просмотреть файл

@ -0,0 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.DotNet.Cli.CommandLine
{
internal static class CommandLineApplicationExtensions
{
public static CommandOption Option(this CommandLineApplication command, string template, string description)
=> command.Option(
template,
description,
template.IndexOf('<') != -1
? template.EndsWith(">...")
? CommandOptionType.MultipleValue
: CommandOptionType.SingleValue
: CommandOptionType.NoValue);
}
}

Просмотреть файл

@ -0,0 +1,135 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class CommandOption
{
public CommandOption(string template, CommandOptionType optionType)
{
Template = template;
OptionType = optionType;
Values = new List<string>();
foreach (var part in Template.Split(new[] { ' ', '|' }, StringSplitOptions.RemoveEmptyEntries))
{
if (part.StartsWith("--"))
{
LongName = part.Substring(2);
}
else if (part.StartsWith("-"))
{
var optName = part.Substring(1);
// If there is only one char and it is not an English letter, it is a symbol option (e.g. "-?")
if (optName.Length == 1 && !IsEnglishLetter(optName[0]))
{
SymbolName = optName;
}
else
{
ShortName = optName;
}
}
else if (part.StartsWith("<") && part.EndsWith(">"))
{
ValueName = part.Substring(1, part.Length - 2);
}
else if (optionType == CommandOptionType.MultipleValue && part.StartsWith("<") && part.EndsWith(">..."))
{
ValueName = part.Substring(1, part.Length - 5);
}
else
{
throw new ArgumentException($"Invalid template pattern '{template}'", nameof(template));
}
}
if (string.IsNullOrEmpty(LongName) && string.IsNullOrEmpty(ShortName) && string.IsNullOrEmpty(SymbolName))
{
throw new ArgumentException($"Invalid template pattern '{template}'", nameof(template));
}
}
public string Template { get; set; }
public string ShortName { get; set; }
public string LongName { get; set; }
public string SymbolName { get; set; }
public string ValueName { get; set; }
public string Description { get; set; }
public List<string> Values { get; private set; }
public bool? BoolValue { get; private set; }
public CommandOptionType OptionType { get; private set; }
public bool TryParse(string value)
{
switch (OptionType)
{
case CommandOptionType.MultipleValue:
Values.Add(value);
break;
case CommandOptionType.SingleValue:
if (Values.Any())
{
return false;
}
Values.Add(value);
break;
case CommandOptionType.BoolValue:
if (Values.Any())
{
return false;
}
if (value == null)
{
// add null to indicate that the option was present, but had no value
Values.Add(null);
BoolValue = true;
}
else
{
bool boolValue;
if (!bool.TryParse(value, out boolValue))
{
return false;
}
Values.Add(value);
BoolValue = boolValue;
}
break;
case CommandOptionType.NoValue:
if (value != null)
{
return false;
}
// Add a value to indicate that this option was specified
Values.Add("on");
break;
default:
break;
}
return true;
}
public bool HasValue()
{
return Values.Any();
}
public string Value()
{
return HasValue() ? Values[0] : null;
}
private bool IsEnglishLetter(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.DotNet.Cli.CommandLine
{
internal enum CommandOptionType
{
MultipleValue,
SingleValue,
BoolValue,
NoValue
}
}

Просмотреть файл

@ -0,0 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.DotNet.Cli.CommandLine
{
internal class CommandParsingException : Exception
{
public CommandParsingException(CommandLineApplication command, string message)
: base(message)
{
Command = command;
}
public CommandLineApplication Command { get; }
}
}

Просмотреть файл

@ -0,0 +1,37 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal abstract class CommandBase
{
public virtual void Configure(CommandLineApplication command)
{
var verbose = command.Option("-v|--verbose", Resources.VerboseDescription);
var noColor = command.Option("--no-color", Resources.NoColorDescription);
var prefixOutput = command.Option("--prefix-output", Resources.PrefixDescription);
command.OnExecute(
() =>
{
Reporter.IsVerbose = verbose.HasValue();
Reporter.NoColor = noColor.HasValue();
Reporter.PrefixOutput = prefixOutput.HasValue();
Validate();
return Execute();
});
}
protected virtual void Validate()
{
}
protected virtual int Execute()
=> 0;
}
}

Просмотреть файл

@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal class ContextCommandBase : ProjectCommandBase
{
private CommandOption _context;
protected CommandOption Context
=> _context;
public override void Configure(CommandLineApplication command)
{
_context = command.Option("-c|--context <DBCONTEXT>", Resources.ContextDescription);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,21 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal class DatabaseCommand : HelpCommandBase
{
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.DatabaseDescription;
command.Command("drop", new DatabaseDropCommand().Configure);
command.Command("update", new DatabaseUpdateCommand().Configure);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal partial class DatabaseDropCommand : ContextCommandBase
{
private CommandOption _force;
private CommandOption _dryRun;
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.DatabaseDropDescription;
_force = command.Option("-f|--force", Resources.DatabaseDropForceDescription);
_dryRun = command.Option("--dry-run", Resources.DatabaseDropDryRunDescription);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,41 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
partial class DatabaseDropCommand
{
protected override int Execute()
{
var executor = CreateExecutor();
var result = executor.GetContextInfo(Context.Value());
var databaseName = result["DatabaseName"] as string;
var dataSource = result["DataSource"] as string;
if (_dryRun.HasValue())
{
Reporter.WriteInformation(Resources.DatabaseDropDryRun(databaseName, dataSource));
return 0;
}
if (!_force.HasValue())
{
Reporter.WriteInformation(Resources.DatabaseDropPrompt(databaseName, dataSource));
var response = Console.ReadLine().Trim().ToUpperInvariant();
if (response != "Y")
{
return 1;
}
}
executor.DropDatabase(Context.Value());
return base.Execute();
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal partial class DatabaseUpdateCommand : ContextCommandBase
{
private CommandArgument _migration;
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.DatabaseUpdateDescription;
_migration = command.Argument("<MIGRATION>", Resources.MigrationDescription);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,15 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
partial class DatabaseUpdateCommand
{
protected override int Execute()
{
CreateExecutor().UpdateDatabase(_migration.Value, Context.Value());
return base.Execute();
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal class DbContextCommand : HelpCommandBase
{
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.DbContextDescription;
command.Command("info", new DbContextInfoCommand().Configure);
command.Command("list", new DbContextListCommand().Configure);
command.Command("scaffold", new DbContextScaffoldCommand().Configure);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal partial class DbContextInfoCommand : ContextCommandBase
{
private CommandOption _json;
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.DbContextInfoDescription;
_json = Json.ConfigureOption(command);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,41 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
partial class DbContextInfoCommand
{
protected override int Execute()
{
var result = CreateExecutor().GetContextInfo(Context.Value());
if (_json.HasValue())
{
ReportJsonResult(result);
}
else
{
ReportResult(result);
}
return base.Execute();
}
private static void ReportJsonResult(IDictionary result)
{
Reporter.WriteData("{");
Reporter.WriteData(" \"databaseName\": \"" + Json.Escape(result["DatabaseName"] as string) + "\",");
Reporter.WriteData(" \"dataSource\": \"" + Json.Escape(result["DataSource"] as string) + "\"");
Reporter.WriteData("}");
}
private static void ReportResult(IDictionary result)
{
Reporter.WriteData(Resources.DatabaseName(result["DatabaseName"]));
Reporter.WriteData(Resources.DataSource(result["DataSource"]));
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal partial class DbContextListCommand : ProjectCommandBase
{
private CommandOption _json;
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.DbContextListDescription;
_json = Json.ConfigureOption(command);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,77 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
partial class DbContextListCommand
{
protected override int Execute()
{
var types = CreateExecutor().GetContextTypes().ToList();
if (_json.HasValue())
{
ReportJsonResults(types);
}
else
{
ReportResults(types);
}
return base.Execute();
}
private static void ReportJsonResults(IReadOnlyList<IDictionary> contextTypes)
{
var nameGroups = contextTypes.GroupBy(t => t["Name"]).ToList();
var fullNameGroups = contextTypes.GroupBy(t => t["FullName"]).ToList();
Reporter.WriteData("[");
for (var i = 0; i < contextTypes.Count; i++)
{
var safeName = nameGroups.Count(g => g.Key == contextTypes[i]["Name"]) == 1
? contextTypes[i]["Name"]
: fullNameGroups.Count(g => g.Key == contextTypes[i]["FullName"]) == 1
? contextTypes[i]["FullName"]
: contextTypes[i]["AssemblyQualifiedName"];
Reporter.WriteData(" {");
Reporter.WriteData(" \"fullName\": \"" + contextTypes[i]["FullName"] + "\",");
Reporter.WriteData(" \"safeName\": \"" + safeName + "\",");
Reporter.WriteData(" \"name\": \"" + contextTypes[i]["Name"] + "\",");
Reporter.WriteData(" \"assemblyQualifiedName\": \"" + contextTypes[i]["AssemblyQualifiedName"] + "\"");
var line = " }";
if (i != contextTypes.Count - 1)
{
line += ",";
}
Reporter.WriteData(line);
}
Reporter.WriteData("]");
}
private static void ReportResults(IEnumerable<IDictionary> contextTypes)
{
var any = false;
foreach (var contextType in contextTypes)
{
Reporter.WriteData(contextType["FullName"] as string);
any = true;
}
if (!any)
{
Reporter.WriteInformation(Resources.NoDbContext);
}
}
}
}

Просмотреть файл

@ -0,0 +1,39 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal partial class DbContextScaffoldCommand : ProjectCommandBase
{
private CommandArgument _connection;
private CommandArgument _provider;
private CommandOption _dataAnnotations;
private CommandOption _context;
private CommandOption _force;
private CommandOption _outputDir;
private CommandOption _schemas;
private CommandOption _tables;
private CommandOption _json;
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.DbContextScaffoldDescription;
_connection = command.Argument("<CONNECTION>", Resources.ConnectionDescription);
_provider = command.Argument("<PROVIDER>", Resources.ProviderDescription);
_dataAnnotations = command.Option("-d|--data-annotations", Resources.DataAnnotationsDescription);
_context = command.Option("-c|--context <NAME>", Resources.ContextNameDescription);
_force = command.Option("-f|--force", Resources.DbContextScaffoldForceDescription);
_outputDir = command.Option("-o|--output-dir <PATH>", Resources.OutputDirDescription);
_schemas = command.Option("--schema <SCHEMA_NAME>...", Resources.SchemasDescription);
_tables = command.Option("-t|--table <TABLE_NAME>...", Resources.TablesDescription);
_json = Json.ConfigureOption(command);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,64 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
partial class DbContextScaffoldCommand
{
protected override void Validate()
{
base.Validate();
if (string.IsNullOrEmpty(_connection.Value))
{
throw new CommandException(Resources.MissingArgument(_connection.Name));
}
if (string.IsNullOrEmpty(_provider.Value))
{
throw new CommandException(Resources.MissingArgument(_provider.Name));
}
}
protected override int Execute()
{
var filesCreated = CreateExecutor().ScaffoldContext(
_provider.Value,
_connection.Value,
_outputDir.Value(),
_context.Value(),
_schemas.Values,
_tables.Values,
_dataAnnotations.HasValue(),
_force.HasValue())
.ToList();
if (_json.HasValue())
{
ReportJsonResults(filesCreated);
}
return base.Execute();
}
private void ReportJsonResults(IReadOnlyList<string> files)
{
Reporter.WriteData("[");
for (var i = 0; i < files.Count; i++)
{
var line = " \"" + Json.Escape(files[i]) + "\"";
if (i != files.Count - 1)
{
line += ",";
}
Reporter.WriteData(line);
}
Reporter.WriteData("]");
}
}
}

Просмотреть файл

@ -0,0 +1,17 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal abstract class EFCommandBase : CommandBase
{
public override void Configure(CommandLineApplication command)
{
command.HelpOption("-h|--help");
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal class EnvironmentCommandBase : EFCommandBase
{
private CommandOption _environment;
protected CommandOption Environment
=> _environment;
public override void Configure(CommandLineApplication command)
{
_environment = command.Option("-e|--environment <NAME>", Resources.EnvironmentDescription);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,26 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal class HelpCommandBase : EFCommandBase
{
private CommandLineApplication _command;
public override void Configure(CommandLineApplication command)
{
_command = command;
base.Configure(command);
}
protected override int Execute()
{
_command.ShowHelp();
return base.Execute();
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal partial class MigrationsAddCommand : ContextCommandBase
{
private CommandArgument _name;
private CommandOption _outputDir;
private CommandOption _json;
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.MigrationsAddDescription;
_name = command.Argument("<NAME>", Resources.MigrationNameDescription);
_outputDir = command.Option("-o|--output-dir <PATH>", Resources.MigrationsOutputDirDescription);
_json = Json.ConfigureOption(command);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,46 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
partial class MigrationsAddCommand
{
protected override void Validate()
{
base.Validate();
if (string.IsNullOrEmpty(_name.Value))
{
throw new CommandException(Resources.MissingArgument(_name.Name));
}
}
protected override int Execute()
{
var files = CreateExecutor().AddMigration(_name.Value, _outputDir.Value(), Context.Value());
if (_json.HasValue())
{
ReportJson(files);
}
else
{
Reporter.WriteInformation(Resources.MigrationsAddCompleted);
}
return base.Execute();
}
private static void ReportJson(IDictionary files)
{
Reporter.WriteData("{");
Reporter.WriteData(" \"migrationFile\": \"" + Json.Escape(files["MigrationFile"] as string) + "\",");
Reporter.WriteData(" \"metadataFile\": \"" + Json.Escape(files["MetadataFile"] as string) + "\",");
Reporter.WriteData(" \"snapshotFile\": \"" + Json.Escape(files["SnapshotFile"] as string) + "\"");
Reporter.WriteData("}");
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal class MigrationsCommand : HelpCommandBase
{
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.MigrationsDescription;
command.Command("add", new MigrationsAddCommand().Configure);
command.Command("list", new MigrationsListCommand().Configure);
command.Command("remove", new MigrationsRemoveCommand().Configure);
command.Command("script", new MigrationsScriptCommand().Configure);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal partial class MigrationsListCommand : ContextCommandBase
{
private CommandOption _json;
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.MigrationsListDescription;
_json = Json.ConfigureOption(command);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,73 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
partial class MigrationsListCommand
{
protected override int Execute()
{
var migrations = CreateExecutor().GetMigrations(Context.Value()).ToList();
if (_json.HasValue())
{
ReportJsonResults(migrations);
}
else
{
ReportResults(migrations);
}
return base.Execute();
}
private static void ReportJsonResults(IReadOnlyList<IDictionary> migrations)
{
var nameGroups = migrations.GroupBy(m => m["Name"]).ToList();
Reporter.WriteData("[");
for (var i = 0; i < migrations.Count; i++)
{
var safeName = nameGroups.Count(g => g.Key == migrations[i]["Name"]) == 1
? migrations[i]["Name"]
: migrations[i]["Id"];
Reporter.WriteData(" {");
Reporter.WriteData(" \"id\": \"" + migrations[i]["Id"] + "\",");
Reporter.WriteData(" \"name\": \"" + migrations[i]["Name"] + "\",");
Reporter.WriteData(" \"safeName\": \"" + safeName + "\"");
var line = " }";
if (i != migrations.Count - 1)
{
line += ",";
}
Reporter.WriteData(line);
}
Reporter.WriteData("]");
}
private static void ReportResults(IEnumerable<IDictionary> migrations)
{
var any = false;
foreach (var migration in migrations)
{
Reporter.WriteData(migration["Id"] as string);
any = true;
}
if (!any)
{
Reporter.WriteInformation(Resources.NoMigrations);
}
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal partial class MigrationsRemoveCommand : ContextCommandBase
{
private CommandOption _force;
private CommandOption _json;
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.MigrationsRemoveDescription;
_force = command.Option("-f|--force", Resources.MigrationsRemoveForceDescription);
_json = Json.ConfigureOption(command);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,40 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
partial class MigrationsRemoveCommand
{
protected override int Execute()
{
var deletedFiles = CreateExecutor().RemoveMigration(Context.Value(), _force.HasValue()).ToList();
if (_json.HasValue())
{
ReportJsonResults(deletedFiles);
}
return base.Execute();
}
private void ReportJsonResults(IReadOnlyList<string> files)
{
Reporter.WriteData("[");
for (var i = 0; i < files.Count; i++)
{
var line = " \"" + Json.Escape(files[i]) + "\"";
if (i != files.Count - 1)
{
line += ",";
}
Reporter.WriteData(line);
}
Reporter.WriteData("]");
}
}
}

Просмотреть файл

@ -0,0 +1,29 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal partial class MigrationsScriptCommand : ContextCommandBase
{
private CommandArgument _from;
private CommandArgument _to;
private CommandOption _output;
private CommandOption _idempotent;
public override void Configure(CommandLineApplication command)
{
command.Description = Resources.MigrationsScriptDescription;
_from = command.Argument("<FROM>", Resources.MigrationFromDescription);
_to = command.Argument("<TO>", Resources.MigrationToDescription);
_output = command.Option("-o|--output <FILE>", Resources.OutputDescription);
_idempotent = command.Option("-i|--idempotent", Resources.IdempotentDescription);
base.Configure(command);
}
}
}

Просмотреть файл

@ -0,0 +1,39 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using System.Text;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
partial class MigrationsScriptCommand
{
protected override int Execute()
{
var sql = CreateExecutor().ScriptMigration(
_from.Value,
_to.Value,
_idempotent.HasValue(),
Context.Value());
if (!_output.HasValue())
{
Reporter.WriteData(sql);
}
else
{
var directory = Path.GetDirectoryName(_output.Value());
if (!string.IsNullOrEmpty(directory))
{
Directory.CreateDirectory(directory);
}
Reporter.WriteVerbose(Resources.WritingFile(_output.Value()));
File.WriteAllText(_output.Value(), sql, Encoding.UTF8);
}
return base.Execute();
}
}
}

Просмотреть файл

@ -0,0 +1,68 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal abstract class ProjectCommandBase : EnvironmentCommandBase
{
private CommandOption _assembly;
private CommandOption _startupAssembly;
private CommandOption _dataDir;
private CommandOption _projectDir;
private CommandOption _contentRoot;
private CommandOption _rootNamespace;
private CommandOption _noAppDomain;
public override void Configure(CommandLineApplication command)
{
_assembly = command.Option("-a|--assembly <PATH>", Resources.AssemblyDescription);
_noAppDomain = command.Option("--no-appdomain", Resources.NoAppDomainDescription);
_startupAssembly = command.Option("-s|--startup-assembly <PATH>", Resources.StartupAssemblyDescription);
_dataDir = command.Option("--data-dir <PATH>", Resources.DataDirDescription);
_projectDir = command.Option("--project-dir <PATH>", Resources.ProjectDirDescription);
_contentRoot = command.Option("--content-root <PATH>", Resources.ContentRootDescription);
_rootNamespace = command.Option("--root-namespace <NAMESPACE>", Resources.RootNamespaceDescription);
base.Configure(command);
}
protected override void Validate()
{
base.Validate();
if (!_assembly.HasValue())
{
throw new CommandException(Resources.MissingOption(_assembly.LongName));
}
}
protected IOperationExecutor CreateExecutor()
{
// TODO: Re-throw TypeLoadException and FileNotFoundException?
#if NET451
if (!_noAppDomain.HasValue())
{
return new AppDomainOperationExecutor(
_assembly.Value(),
_startupAssembly.Value(),
_projectDir.Value(),
_contentRoot.Value(),
_dataDir.Value(),
_rootNamespace.Value(),
Environment.Value());
}
#endif
return new ReflectionOperationExecutor(
_assembly.Value(),
_startupAssembly.Value(),
_projectDir.Value(),
_contentRoot.Value(),
_dataDir.Value(),
_rootNamespace.Value(),
Environment.Value());
}
}
}

Просмотреть файл

@ -0,0 +1,49 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
using Microsoft.DotNet.Cli.CommandLine;
using static Microsoft.EntityFrameworkCore.Tools.AnsiConstants;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools.Commands
{
internal class RootCommand : HelpCommandBase
{
public override void Configure(CommandLineApplication command)
{
command.FullName = Resources.EFFullName;
// NB: Update ShouldHelp in dotnet-ef when adding new command groups
command.Command("database", new DatabaseCommand().Configure);
command.Command("dbcontext", new DbContextCommand().Configure);
command.Command("migrations", new MigrationsCommand().Configure);
command.VersionOption("--version", GetVersion);
base.Configure(command);
}
protected override int Execute()
{
Reporter.WriteInformation(
string.Join(
Environment.NewLine,
string.Empty,
Reporter.Colorize(@" _/\__ ", s => s.Insert(21, Bold + Gray)),
Reporter.Colorize(@" ---==/ \\ ", s => s.Insert(20, Bold + Gray)),
Reporter.Colorize(@" ___ ___ |. \|\ ", s => s.Insert(26, Bold).Insert(21, Dark).Insert(20, Bold + Gray).Insert(9, Dark + Magenta)),
Reporter.Colorize(@" | __|| __| | ) \\\ ", s => s.Insert(20, Bold + Gray).Insert(8, Dark + Magenta)),
Reporter.Colorize(@" | _| | _| \_/ | //|\\ ", s => s.Insert(20, Bold + Gray).Insert(8, Dark + Magenta)),
Reporter.Colorize(@" |___||_| / \\\/\\", s => s.Insert(33, Reset).Insert(23, Bold + Gray).Insert(8, Dark + Magenta)),
string.Empty));
return base.Execute();
}
private static string GetVersion()
=> typeof(RootCommand).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
.InformationalVersion;
}
}

Просмотреть файл

@ -0,0 +1,33 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections;
using System.Collections.Generic;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal interface IOperationExecutor : IDisposable
{
IDictionary AddMigration(string name, string outputDir, string contextType);
IEnumerable<string> RemoveMigration(string contextType, bool force);
IEnumerable<IDictionary> GetMigrations(string contextType);
void DropDatabase(string contextType);
IDictionary GetContextInfo(string name);
string GetContextType(string name);
void UpdateDatabase(string migration, string contextType);
IEnumerable<IDictionary> GetContextTypes();
IEnumerable<string> ScaffoldContext(
string provider,
string connectionString,
string outputDir,
string dbContextClassName,
IEnumerable<string> schemaFilters,
IEnumerable<string> tableFilters,
bool useDataAnnotations,
bool overwriteFiles);
string ScriptMigration(string fromMigration, string toMigration, bool idempotent, string contextType);
}
}

17
src/ef/Json.cs Normal file
Просмотреть файл

@ -0,0 +1,17 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal static class Json
{
public static CommandOption ConfigureOption(CommandLineApplication command)
=> command.Option("--json", Resources.JsonDescription);
public static string Escape(string text)
=> text.Replace("\\", "\\\\").Replace("\"", "\\\"");
}
}

Просмотреть файл

@ -0,0 +1,200 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Microsoft.EntityFrameworkCore.Tools.Properties;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal abstract class OperationExecutorBase : IOperationExecutor
{
private const string DataDirEnvName = "ADONET_DATA_DIR";
public const string DesignAssemblyName = "Microsoft.EntityFrameworkCore.Design";
protected const string ExecutorTypeName = "Microsoft.EntityFrameworkCore.Design.OperationExecutor";
private static readonly IDictionary EmptyArguments = new Dictionary<string, object>(0);
public string AppBasePath { get; }
protected string AssemblyFileName { get; set; }
protected string StartupAssemblyFileName { get; set; }
protected string ContentRootPath { get; }
protected string ProjectDirectory { get; }
protected string RootNamespace { get; }
protected string EnvironmentName { get; }
protected OperationExecutorBase(
string assembly,
string startupAssembly,
string projectDir,
string contentRootPath,
string dataDirectory,
string rootNamespace,
string environment)
{
AssemblyFileName = Path.GetFileNameWithoutExtension(assembly);
StartupAssemblyFileName = startupAssembly == null
? AssemblyFileName
: Path.GetFileNameWithoutExtension(startupAssembly);
AppBasePath = Path.GetDirectoryName(startupAssembly ?? assembly);
if (!Path.IsPathRooted(AppBasePath))
{
AppBasePath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), AppBasePath));
}
ContentRootPath = contentRootPath ?? AppBasePath;
RootNamespace = rootNamespace ?? AssemblyFileName;
ProjectDirectory = projectDir ?? Directory.GetCurrentDirectory();
EnvironmentName = environment;
Reporter.WriteVerbose(Resources.UsingAssembly(AssemblyFileName));
Reporter.WriteVerbose(Resources.UsingStartupAssembly(StartupAssemblyFileName));
Reporter.WriteVerbose(Resources.UsingApplicationBase(AppBasePath));
Reporter.WriteVerbose(Resources.UsingContentRoot(ContentRootPath));
Reporter.WriteVerbose(Resources.UsingRootNamespace(RootNamespace));
Reporter.WriteVerbose(Resources.UsingProjectDir(ProjectDirectory));
if (dataDirectory != null)
{
Reporter.WriteVerbose(Resources.UsingDataDir(dataDirectory));
Environment.SetEnvironmentVariable(DataDirEnvName, dataDirectory);
}
}
public virtual void Dispose()
{
}
protected abstract dynamic CreateResultHandler();
protected abstract void Execute(string operationName, object resultHandler, IDictionary arguments);
private TResult InvokeOperation<TResult>(string operation)
=> InvokeOperation<TResult>(operation, EmptyArguments);
private TResult InvokeOperation<TResult>(string operation, IDictionary arguments)
=> (TResult)InvokeOperationImpl(operation, arguments);
private void InvokeOperation(string operation, IDictionary arguments)
=> InvokeOperationImpl(operation, arguments);
private object InvokeOperationImpl(string operationName, IDictionary arguments)
{
var resultHandler = CreateResultHandler();
var currentDirectory = Directory.GetCurrentDirectory();
Directory.SetCurrentDirectory(AppBasePath);
try
{
Execute(operationName, resultHandler, arguments);
}
finally
{
Directory.SetCurrentDirectory(currentDirectory);
}
if (resultHandler.ErrorType != null)
{
throw new WrappedException(
resultHandler.ErrorType,
resultHandler.ErrorMessage,
resultHandler.ErrorStackTrace);
}
return resultHandler.Result;
}
public IDictionary AddMigration(string name, string outputDir, string contextType)
=> InvokeOperation<IDictionary>("AddMigration",
new Dictionary<string, string>
{
["name"] = name,
["outputDir"] = outputDir,
["contextType"] = contextType
});
public IEnumerable<string> RemoveMigration(string contextType, bool force)
=> InvokeOperation<IEnumerable<string>>("RemoveMigration",
new Dictionary<string, object>
{
["contextType"] = contextType,
["force"] = force
});
public IEnumerable<IDictionary> GetMigrations(string contextType)
=> InvokeOperation<IEnumerable<IDictionary>>("GetMigrations",
new Dictionary<string, object>
{
["contextType"] = contextType
});
public void DropDatabase(string contextType)
=> InvokeOperation("DropDatabase",
new Dictionary<string, object>
{
["contextType"] = contextType
});
public IDictionary GetContextInfo(string name)
=> InvokeOperation<IDictionary>("GetContextInfo",
new Dictionary<string, object>
{
["contextType"] = name
});
public void UpdateDatabase(string migration, string contextType)
=> InvokeOperation("UpdateDatabase",
new Dictionary<string, string>
{
["targetMigration"] = migration,
["contextType"] = contextType
});
public IEnumerable<IDictionary> GetContextTypes()
=> InvokeOperation<IEnumerable<IDictionary>>("GetContextTypes");
public IEnumerable<string> ScaffoldContext(string provider,
string connectionString,
string outputDir,
string dbContextClassName,
IEnumerable<string> schemaFilters,
IEnumerable<string> tableFilters,
bool useDataAnnotations,
bool overwriteFiles)
=> InvokeOperation<IEnumerable<string>>("ScaffoldContext",
new Dictionary<string, object>
{
["provider"] = provider,
["connectionString"] = connectionString,
["outputDir"] = outputDir,
["dbContextClassName"] = dbContextClassName,
["schemaFilters"] = schemaFilters,
["tableFilters"] = tableFilters,
["useDataAnnotations"] = useDataAnnotations,
["overwriteFiles"] = overwriteFiles
});
public string ScriptMigration(
string fromMigration,
string toMigration,
bool idempotent,
string contextType)
=> InvokeOperation<string>("ScriptMigration",
new Dictionary<string, object>
{
["fromMigration"] = fromMigration,
["toMigration"] = toMigration,
["idempotent"] = idempotent,
["contextType"] = contextType
});
public string GetContextType(string name)
=> InvokeOperation<string>("GetContextType",
new Dictionary<string, string>
{
["name"] = name
});
}
}

46
src/ef/Program.cs Normal file
Просмотреть файл

@ -0,0 +1,46 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Commands;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal static class Program
{
private static int Main(string[] args)
{
var app = new CommandLineApplication()
{
Name = "ef"
};
new RootCommand().Configure(app);
try
{
return app.Execute(args);
}
catch (Exception ex)
{
var wrappedException = ex as WrappedException;
if (ex is CommandException
|| ex is CommandParsingException
|| (wrappedException != null
&& wrappedException.Type == "Microsoft.EntityFrameworkCore.Design.OperationException"))
{
Reporter.WriteVerbose(ex.ToString());
}
else
{
Reporter.WriteInformation(ex.ToString());
}
Reporter.WriteError(ex.Message);
return 1;
}
}
}
}

Просмотреть файл

@ -0,0 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo(
"ef.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

431
src/ef/Properties/Resources.Designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,431 @@
// <auto-generated />
using System.Reflection;
using System.Resources;
using JetBrains.Annotations;
namespace Microsoft.EntityFrameworkCore.Tools.Properties
{
/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
internal static class Resources
{
private static readonly ResourceManager _resourceManager
= new ResourceManager("Microsoft.EntityFrameworkCore.Tools.Properties.Resources", typeof(Resources).GetTypeInfo().Assembly);
/// <summary>
/// The assembly to use.
/// </summary>
public static string AssemblyDescription
=> GetString("AssemblyDescription");
/// <summary>
/// The connection string to the database.
/// </summary>
public static string ConnectionDescription
=> GetString("ConnectionDescription");
/// <summary>
/// The content root path. Defaults to the startup assembly directory.
/// </summary>
public static string ContentRootDescription
=> GetString("ContentRootDescription");
/// <summary>
/// The DbContext to use.
/// </summary>
public static string ContextDescription
=> GetString("ContextDescription");
/// <summary>
/// The name of the DbContext.
/// </summary>
public static string ContextNameDescription
=> GetString("ContextNameDescription");
/// <summary>
/// Use attributes to configure the model (where possible). If omitted, only the fluent API is used.
/// </summary>
public static string DataAnnotationsDescription
=> GetString("DataAnnotationsDescription");
/// <summary>
/// Commands to manage the database.
/// </summary>
public static string DatabaseDescription
=> GetString("DatabaseDescription");
/// <summary>
/// Drops the database.
/// </summary>
public static string DatabaseDropDescription
=> GetString("DatabaseDropDescription");
/// <summary>
/// This would drop the database '{database}' on server '{dataSource}'.
/// </summary>
public static string DatabaseDropDryRun([CanBeNull] object database, [CanBeNull] object dataSource)
=> string.Format(
GetString("DatabaseDropDryRun", nameof(database), nameof(dataSource)),
database, dataSource);
/// <summary>
/// Show which database would be dropped, but don't drop it.
/// </summary>
public static string DatabaseDropDryRunDescription
=> GetString("DatabaseDropDryRunDescription");
/// <summary>
/// Don't confirm.
/// </summary>
public static string DatabaseDropForceDescription
=> GetString("DatabaseDropForceDescription");
/// <summary>
/// Are you sure you want to drop the database '{database}' on server '{dataSource}'? (y/N)
/// </summary>
public static string DatabaseDropPrompt([CanBeNull] object database, [CanBeNull] object dataSource)
=> string.Format(
GetString("DatabaseDropPrompt", nameof(database), nameof(dataSource)),
database, dataSource);
/// <summary>
/// Database name: {database}
/// </summary>
public static string DatabaseName([CanBeNull] object database)
=> string.Format(
GetString("DatabaseName", nameof(database)),
database);
/// <summary>
/// Updates the database to a specified migration.
/// </summary>
public static string DatabaseUpdateDescription
=> GetString("DatabaseUpdateDescription");
/// <summary>
/// The data directory.
/// </summary>
public static string DataDirDescription
=> GetString("DataDirDescription");
/// <summary>
/// Data source: {dataSource}
/// </summary>
public static string DataSource([CanBeNull] object dataSource)
=> string.Format(
GetString("DataSource", nameof(dataSource)),
dataSource);
/// <summary>
/// Commands to manage DbContext types.
/// </summary>
public static string DbContextDescription
=> GetString("DbContextDescription");
/// <summary>
/// Gets information about a DbContext type.
/// </summary>
public static string DbContextInfoDescription
=> GetString("DbContextInfoDescription");
/// <summary>
/// Lists available DbContext types.
/// </summary>
public static string DbContextListDescription
=> GetString("DbContextListDescription");
/// <summary>
/// Scaffolds a DbContext and entity types for a database.
/// </summary>
public static string DbContextScaffoldDescription
=> GetString("DbContextScaffoldDescription");
/// <summary>
/// Overwrite existing files.
/// </summary>
public static string DbContextScaffoldForceDescription
=> GetString("DbContextScaffoldForceDescription");
/// <summary>
/// Entity Framework Core Command Line Tools
/// </summary>
public static string EFFullName
=> GetString("EFFullName");
/// <summary>
/// The environment to use. Defaults to "Development".
/// </summary>
public static string EnvironmentDescription
=> GetString("EnvironmentDescription");
/// <summary>
/// Generate a script that can be used on a database at any migration.
/// </summary>
public static string IdempotentDescription
=> GetString("IdempotentDescription");
/// <summary>
/// Show JSON output.
/// </summary>
public static string JsonDescription
=> GetString("JsonDescription");
/// <summary>
/// The target migration. If '0', all migrations will be reverted. Defaults to the last migration.
/// </summary>
public static string MigrationDescription
=> GetString("MigrationDescription");
/// <summary>
/// The starting migration. Defaults to '0' (the initial database).
/// </summary>
public static string MigrationFromDescription
=> GetString("MigrationFromDescription");
/// <summary>
/// The name of the migration.
/// </summary>
public static string MigrationNameDescription
=> GetString("MigrationNameDescription");
/// <summary>
/// Done. To undo this action, use 'ef migrations remove'
/// </summary>
public static string MigrationsAddCompleted
=> GetString("MigrationsAddCompleted");
/// <summary>
/// Adds a new migration.
/// </summary>
public static string MigrationsAddDescription
=> GetString("MigrationsAddDescription");
/// <summary>
/// Commands to manage migrations.
/// </summary>
public static string MigrationsDescription
=> GetString("MigrationsDescription");
/// <summary>
/// Lists available migrations.
/// </summary>
public static string MigrationsListDescription
=> GetString("MigrationsListDescription");
/// <summary>
/// The directory (and sub-namespace) to use. Paths are relative to the project directory. Defaults to "Migrations".
/// </summary>
public static string MigrationsOutputDirDescription
=> GetString("MigrationsOutputDirDescription");
/// <summary>
/// Removes the last migration.
/// </summary>
public static string MigrationsRemoveDescription
=> GetString("MigrationsRemoveDescription");
/// <summary>
/// Don't check to see if the migration has been applied to the database.
/// </summary>
public static string MigrationsRemoveForceDescription
=> GetString("MigrationsRemoveForceDescription");
/// <summary>
/// Generates a SQL script from migrations.
/// </summary>
public static string MigrationsScriptDescription
=> GetString("MigrationsScriptDescription");
/// <summary>
/// The ending migration. Defaults to the last migration.
/// </summary>
public static string MigrationToDescription
=> GetString("MigrationToDescription");
/// <summary>
/// Missing required argument '{arg}'.
/// </summary>
public static string MissingArgument([CanBeNull] object arg)
=> string.Format(
GetString("MissingArgument", nameof(arg)),
arg);
/// <summary>
/// Missing required option '--{option}'.
/// </summary>
public static string MissingOption([CanBeNull] object option)
=> string.Format(
GetString("MissingOption", nameof(option)),
option);
/// <summary>
/// Don't use app domains. Always implied on .NET Core.
/// </summary>
public static string NoAppDomainDescription
=> GetString("NoAppDomainDescription");
/// <summary>
/// Don't colorize output.
/// </summary>
public static string NoColorDescription
=> GetString("NoColorDescription");
/// <summary>
/// No DbContext was found.
/// </summary>
public static string NoDbContext
=> GetString("NoDbContext");
/// <summary>
/// No migrations were found.
/// </summary>
public static string NoMigrations
=> GetString("NoMigrations");
/// <summary>
/// The file to write the result to.
/// </summary>
public static string OutputDescription
=> GetString("OutputDescription");
/// <summary>
/// The directory to put files in. Paths are relative to the project directory.
/// </summary>
public static string OutputDirDescription
=> GetString("OutputDirDescription");
/// <summary>
/// Prefix output with level.
/// </summary>
public static string PrefixDescription
=> GetString("PrefixDescription");
/// <summary>
/// The project directory. Defaults to the current directory.
/// </summary>
public static string ProjectDirDescription
=> GetString("ProjectDirDescription");
/// <summary>
/// The provider to use. (E.g. Microsoft.EntityFrameworkCore.SqlServer)
/// </summary>
public static string ProviderDescription
=> GetString("ProviderDescription");
/// <summary>
/// The root namespace. Defaults to the target assembly name.
/// </summary>
public static string RootNamespaceDescription
=> GetString("RootNamespaceDescription");
/// <summary>
/// The schemas of tables to generate entity types for.
/// </summary>
public static string SchemasDescription
=> GetString("SchemasDescription");
/// <summary>
/// The startup assembly to use. Defaults to the target assembly.
/// </summary>
public static string StartupAssemblyDescription
=> GetString("StartupAssemblyDescription");
/// <summary>
/// The tables to generate entity types for.
/// </summary>
public static string TablesDescription
=> GetString("TablesDescription");
/// <summary>
/// Using application base '{appBase}'.
/// </summary>
public static string UsingApplicationBase([CanBeNull] object appBase)
=> string.Format(
GetString("UsingApplicationBase", nameof(appBase)),
appBase);
/// <summary>
/// Using assembly '{assembly}'.
/// </summary>
public static string UsingAssembly([CanBeNull] object assembly)
=> string.Format(
GetString("UsingAssembly", nameof(assembly)),
assembly);
/// <summary>
/// Using configuration file '{config}'.
/// </summary>
public static string UsingConfigurationFile([CanBeNull] object config)
=> string.Format(
GetString("UsingConfigurationFile", nameof(config)),
config);
/// <summary>
/// Using content root '{contentRoot}'.
/// </summary>
public static string UsingContentRoot([CanBeNull] object contentRoot)
=> string.Format(
GetString("UsingContentRoot", nameof(contentRoot)),
contentRoot);
/// <summary>
/// Using data directory '{dataDir}'.
/// </summary>
public static string UsingDataDir([CanBeNull] object dataDir)
=> string.Format(
GetString("UsingDataDir", nameof(dataDir)),
dataDir);
/// <summary>
/// Using project directory '{projectDir}'.
/// </summary>
public static string UsingProjectDir([CanBeNull] object projectDir)
=> string.Format(
GetString("UsingProjectDir", nameof(projectDir)),
projectDir);
/// <summary>
/// Using root namespace '{rootNamespace}'.
/// </summary>
public static string UsingRootNamespace([CanBeNull] object rootNamespace)
=> string.Format(
GetString("UsingRootNamespace", nameof(rootNamespace)),
rootNamespace);
/// <summary>
/// Using startup assembly '{startupAssembly}'.
/// </summary>
public static string UsingStartupAssembly([CanBeNull] object startupAssembly)
=> string.Format(
GetString("UsingStartupAssembly", nameof(startupAssembly)),
startupAssembly);
/// <summary>
/// Show verbose output.
/// </summary>
public static string VerboseDescription
=> GetString("VerboseDescription");
/// <summary>
/// Writing '{file}'...
/// </summary>
public static string WritingFile([CanBeNull] object file)
=> string.Format(
GetString("WritingFile", nameof(file)),
file);
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
for (var i = 0; i < formatterNames.Length; i++)
{
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
}
return value;
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<#
Session["ResourceFile"] = "Resources.resx";
Session["AccessModifier"] = "internal";
#>
<#@ include file="..\..\..\tools\Resources.tt" #>

Просмотреть файл

@ -0,0 +1,306 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AssemblyDescription" xml:space="preserve">
<value>The assembly to use.</value>
</data>
<data name="ConnectionDescription" xml:space="preserve">
<value>The connection string to the database.</value>
</data>
<data name="ContentRootDescription" xml:space="preserve">
<value>The content root path. Defaults to the startup assembly directory.</value>
</data>
<data name="ContextDescription" xml:space="preserve">
<value>The DbContext to use.</value>
</data>
<data name="ContextNameDescription" xml:space="preserve">
<value>The name of the DbContext.</value>
</data>
<data name="DataAnnotationsDescription" xml:space="preserve">
<value>Use attributes to configure the model (where possible). If omitted, only the fluent API is used.</value>
</data>
<data name="DatabaseDescription" xml:space="preserve">
<value>Commands to manage the database.</value>
</data>
<data name="DatabaseDropDescription" xml:space="preserve">
<value>Drops the database.</value>
</data>
<data name="DatabaseDropDryRun" xml:space="preserve">
<value>This would drop the database '{database}' on server '{dataSource}'.</value>
</data>
<data name="DatabaseDropDryRunDescription" xml:space="preserve">
<value>Show which database would be dropped, but don't drop it.</value>
</data>
<data name="DatabaseDropForceDescription" xml:space="preserve">
<value>Don't confirm.</value>
</data>
<data name="DatabaseDropPrompt" xml:space="preserve">
<value>Are you sure you want to drop the database '{database}' on server '{dataSource}'? (y/N)</value>
</data>
<data name="DatabaseName" xml:space="preserve">
<value>Database name: {database}</value>
</data>
<data name="DatabaseUpdateDescription" xml:space="preserve">
<value>Updates the database to a specified migration.</value>
</data>
<data name="DataDirDescription" xml:space="preserve">
<value>The data directory.</value>
</data>
<data name="DataSource" xml:space="preserve">
<value>Data source: {dataSource}</value>
</data>
<data name="DbContextDescription" xml:space="preserve">
<value>Commands to manage DbContext types.</value>
</data>
<data name="DbContextInfoDescription" xml:space="preserve">
<value>Gets information about a DbContext type.</value>
</data>
<data name="DbContextListDescription" xml:space="preserve">
<value>Lists available DbContext types.</value>
</data>
<data name="DbContextScaffoldDescription" xml:space="preserve">
<value>Scaffolds a DbContext and entity types for a database.</value>
</data>
<data name="DbContextScaffoldForceDescription" xml:space="preserve">
<value>Overwrite existing files.</value>
</data>
<data name="EFFullName" xml:space="preserve">
<value>Entity Framework Core Command Line Tools</value>
</data>
<data name="EnvironmentDescription" xml:space="preserve">
<value>The environment to use. Defaults to "Development".</value>
</data>
<data name="IdempotentDescription" xml:space="preserve">
<value>Generate a script that can be used on a database at any migration.</value>
</data>
<data name="JsonDescription" xml:space="preserve">
<value>Show JSON output.</value>
</data>
<data name="MigrationDescription" xml:space="preserve">
<value>The target migration. If '0', all migrations will be reverted. Defaults to the last migration.</value>
</data>
<data name="MigrationFromDescription" xml:space="preserve">
<value>The starting migration. Defaults to '0' (the initial database).</value>
</data>
<data name="MigrationNameDescription" xml:space="preserve">
<value>The name of the migration.</value>
</data>
<data name="MigrationsAddCompleted" xml:space="preserve">
<value>Done. To undo this action, use 'ef migrations remove'</value>
</data>
<data name="MigrationsAddDescription" xml:space="preserve">
<value>Adds a new migration.</value>
</data>
<data name="MigrationsDescription" xml:space="preserve">
<value>Commands to manage migrations.</value>
</data>
<data name="MigrationsListDescription" xml:space="preserve">
<value>Lists available migrations.</value>
</data>
<data name="MigrationsOutputDirDescription" xml:space="preserve">
<value>The directory (and sub-namespace) to use. Paths are relative to the project directory. Defaults to "Migrations".</value>
</data>
<data name="MigrationsRemoveDescription" xml:space="preserve">
<value>Removes the last migration.</value>
</data>
<data name="MigrationsRemoveForceDescription" xml:space="preserve">
<value>Don't check to see if the migration has been applied to the database.</value>
</data>
<data name="MigrationsScriptDescription" xml:space="preserve">
<value>Generates a SQL script from migrations.</value>
</data>
<data name="MigrationToDescription" xml:space="preserve">
<value>The ending migration. Defaults to the last migration.</value>
</data>
<data name="MissingArgument" xml:space="preserve">
<value>Missing required argument '{arg}'.</value>
</data>
<data name="MissingOption" xml:space="preserve">
<value>Missing required option '--{option}'.</value>
</data>
<data name="NoAppDomainDescription" xml:space="preserve">
<value>Don't use app domains. Always implied on .NET Core.</value>
</data>
<data name="NoColorDescription" xml:space="preserve">
<value>Don't colorize output.</value>
</data>
<data name="NoDbContext" xml:space="preserve">
<value>No DbContext was found.</value>
</data>
<data name="NoMigrations" xml:space="preserve">
<value>No migrations were found.</value>
</data>
<data name="OutputDescription" xml:space="preserve">
<value>The file to write the result to.</value>
</data>
<data name="OutputDirDescription" xml:space="preserve">
<value>The directory to put files in. Paths are relative to the project directory.</value>
</data>
<data name="PrefixDescription" xml:space="preserve">
<value>Prefix output with level.</value>
</data>
<data name="ProjectDirDescription" xml:space="preserve">
<value>The project directory. Defaults to the current directory.</value>
</data>
<data name="ProviderDescription" xml:space="preserve">
<value>The provider to use. (E.g. Microsoft.EntityFrameworkCore.SqlServer)</value>
</data>
<data name="RootNamespaceDescription" xml:space="preserve">
<value>The root namespace. Defaults to the target assembly name.</value>
</data>
<data name="SchemasDescription" xml:space="preserve">
<value>The schemas of tables to generate entity types for.</value>
</data>
<data name="StartupAssemblyDescription" xml:space="preserve">
<value>The startup assembly to use. Defaults to the target assembly.</value>
</data>
<data name="TablesDescription" xml:space="preserve">
<value>The tables to generate entity types for.</value>
</data>
<data name="UsingApplicationBase" xml:space="preserve">
<value>Using application base '{appBase}'.</value>
</data>
<data name="UsingAssembly" xml:space="preserve">
<value>Using assembly '{assembly}'.</value>
</data>
<data name="UsingConfigurationFile" xml:space="preserve">
<value>Using configuration file '{config}'.</value>
</data>
<data name="UsingContentRoot" xml:space="preserve">
<value>Using content root '{contentRoot}'.</value>
</data>
<data name="UsingDataDir" xml:space="preserve">
<value>Using data directory '{dataDir}'.</value>
</data>
<data name="UsingProjectDir" xml:space="preserve">
<value>Using project directory '{projectDir}'.</value>
</data>
<data name="UsingRootNamespace" xml:space="preserve">
<value>Using root namespace '{rootNamespace}'.</value>
</data>
<data name="UsingStartupAssembly" xml:space="preserve">
<value>Using startup assembly '{startupAssembly}'.</value>
</data>
<data name="VerboseDescription" xml:space="preserve">
<value>Show verbose output.</value>
</data>
<data name="WritingFile" xml:space="preserve">
<value>Writing '{file}'...</value>
</data>
</root>

Просмотреть файл

@ -0,0 +1,100 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
#if NET451
using System.IO;
#endif
namespace Microsoft.EntityFrameworkCore.Tools
{
internal class ReflectionOperationExecutor : OperationExecutorBase
{
private readonly object _executor;
private readonly Assembly _commandsAssembly;
private const string ReportHandlerTypeName = "Microsoft.EntityFrameworkCore.Design.OperationReportHandler";
private const string ResultHandlerTypeName = "Microsoft.EntityFrameworkCore.Design.OperationResultHandler";
private readonly Type _resultHandlerType;
public ReflectionOperationExecutor(
string assembly,
string startupAssembly,
string projectDir,
string contentRootPath,
string dataDirectory,
string rootNamespace,
string environment)
: base(assembly, startupAssembly, projectDir, contentRootPath, dataDirectory, rootNamespace, environment)
{
#if NET451
AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
#endif
_commandsAssembly = Assembly.Load(new AssemblyName { Name = DesignAssemblyName });
var reportHandlerType = _commandsAssembly.GetType(ReportHandlerTypeName, throwOnError: true, ignoreCase: false);
var reportHandler = Activator.CreateInstance(
reportHandlerType,
(Action<string>)Reporter.WriteError,
(Action<string>)Reporter.WriteWarning,
(Action<string>)Reporter.WriteInformation,
(Action<string>)Reporter.WriteVerbose);
_executor = Activator.CreateInstance(
_commandsAssembly.GetType(ExecutorTypeName, throwOnError: true, ignoreCase: false),
reportHandler,
new Dictionary<string, string>
{
{ "targetName", AssemblyFileName },
{ "startupTargetName", StartupAssemblyFileName },
{ "projectDir", ProjectDirectory },
{ "contentRootPath", ContentRootPath },
{ "rootNamespace", RootNamespace },
{ "environment", EnvironmentName }
});
_resultHandlerType = _commandsAssembly.GetType(ResultHandlerTypeName, throwOnError: true, ignoreCase: false);
}
protected override object CreateResultHandler()
=> Activator.CreateInstance(_resultHandlerType);
protected override void Execute(string operationName, object resultHandler, IDictionary arguments)
=> Activator.CreateInstance(
_commandsAssembly.GetType(ExecutorTypeName + "+" + operationName, throwOnError: true, ignoreCase: true),
_executor,
resultHandler,
arguments);
#if NET451
private Assembly ResolveAssembly(object sender, ResolveEventArgs args)
{
var assemblyName = new AssemblyName(args.Name);
foreach (var extension in new[] { ".dll", ".exe" })
{
var path = Path.Combine(AppBasePath, assemblyName.Name + extension);
if (File.Exists(path))
{
try
{
return Assembly.LoadFrom(path);
}
catch
{
}
}
}
return null;
}
public override void Dispose()
=> AppDomain.CurrentDomain.AssemblyResolve -= ResolveAssembly;
#endif
}
}

58
src/ef/Reporter.cs Normal file
Просмотреть файл

@ -0,0 +1,58 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using static Microsoft.EntityFrameworkCore.Tools.AnsiConstants;
namespace Microsoft.EntityFrameworkCore.Tools
{
internal static class Reporter
{
public static bool IsVerbose { get; set; }
public static bool NoColor { get; set; }
public static bool PrefixOutput { get; set; }
public static string Colorize(string value, Func<string, string> colorizeFunc)
=> NoColor ? value : colorizeFunc(value);
public static void WriteError(string message)
=> WriteLine(Prefix("error: ", Colorize(message, x => Bold + Red + x + Reset)));
public static void WriteWarning(string message)
=> WriteLine(Prefix("warn: ", Colorize(message, x => Bold + Yellow + x + Reset)));
public static void WriteInformation(string message)
=> WriteLine(Prefix("info: ", message));
public static void WriteData(string message)
=> WriteLine(Prefix("data: ", Colorize(message, x => Bold + Gray + x + Reset)));
public static void WriteVerbose(string message)
{
if (IsVerbose)
{
WriteLine(Prefix("verbose: ", Colorize(message, x => Bold + Black + x + Reset)));
}
}
private static string Prefix(string prefix, string value)
=> PrefixOutput
? string.Join(
Environment.NewLine,
value.Split(new[] { Environment.NewLine }, StringSplitOptions.None).Select(l => prefix + l))
: value;
private static void WriteLine(string value)
{
if (NoColor)
{
Console.WriteLine(value);
}
else
{
AnsiConsole.WriteLine(value);
}
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
namespace Microsoft.EntityFrameworkCore.Tools
{
public class WrappedException : Exception
{
private readonly string _stackTrace;
public WrappedException(string type, string message, string stackTrace)
: base(message)
{
Type = type;
_stackTrace = stackTrace;
}
public string Type { get; }
public override string ToString()
=> _stackTrace;
}
}

50
src/ef/ef.csproj Normal file
Просмотреть файл

@ -0,0 +1,50 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFrameworks>netcoreapp1.0;net451</TargetFrameworks>
<Description>Entity Framework Core Command Line Tools</Description>
<OutputType>Exe</OutputType>
<AssemblyName Condition="'$(Platform)' == 'x86'">ef.x86</AssemblyName>
<IsPackable>false</IsPackable>
<RootNamespace>Microsoft.EntityFrameworkCore.Tools</RootNamespace>
<RuntimeFrameworkVersion>1.0.0</RuntimeFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Shared\CodeAnnotations.cs" />
<Compile Include="..\EFCore.Design\Design\IOperationReportHandler.cs" />
<Compile Include="..\EFCore.Design\Design\IOperationResultHandler.cs" />
<Compile Include="..\EFCore.Design\Design\OperationReportHandler.cs" />
<Compile Include="..\EFCore.Design\Design\OperationResultHandler.cs" />
</ItemGroup>
<ItemGroup>
<None Update="Properties\Resources.Designer.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.Designer.tt</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<Target Name="BuildX86" AfterTargets="Build">
<MSBuild Projects="$(MSBuildProjectFullPath)" Properties="Platform=x86;Configuration=$(Configuration)" Targets="Build" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Xunit;
namespace Microsoft.EntityFrameworkCore.Tools
{
public class CommandExceptionTest
{
[Fact]
public void Ctor_works()
{
var ex = new CommandException("Message1");
Assert.Equal("Message1", ex.Message);
}
}
}

Просмотреть файл

@ -0,0 +1,74 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using Xunit;
using EFCommand = Microsoft.EntityFrameworkCore.Tools.Commands.RootCommand;
namespace Microsoft.EntityFrameworkCore.Tools
{
public class CommandsTest
{
[Fact]
public void Short_names_are_unique()
{
foreach (var command in GetCommands())
{
foreach (var group in command.Options.GroupBy(o => o.ShortName))
{
Assert.True(
group.Key == null || group.Count() == 1,
"Duplicate short names on command '" + GetFullName(command) + "': " +
string.Join("; ", group.Select(o => o.Template)));
}
}
}
private static IEnumerable<CommandLineApplication> GetCommands()
{
var app = new CommandLineApplication()
{
Name = "dotnet ef"
};
new EFCommand().Configure(app);
return GetCommands(app);
}
private static IEnumerable<CommandLineApplication> GetCommands(CommandLineApplication command)
{
var commands = new Stack<CommandLineApplication>();
commands.Push(command);
while (commands.Count != 0)
{
command = commands.Pop();
yield return command;
foreach (var subcommand in command.Commands)
{
commands.Push(subcommand);
}
}
}
private static string GetFullName(CommandLineApplication command)
{
var names = new Stack<string>();
while (command != null)
{
names.Push(command.Name);
command = command.Parent;
}
return string.Join(" ", names);
}
}
}

Просмотреть файл

@ -0,0 +1,43 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Reflection;
using Xunit;
namespace Microsoft.EntityFrameworkCore.Tools
{
public class ExeTest
{
[Fact]
public void ToArguments_works()
{
var result = ToArguments(
new[] {
"Good",
"Good\\",
"Needs quotes",
"Needs escaping\\",
"Needs escaping\\\\",
"Needs \"escaping\"",
"Needs \\\"escaping\"",
"Needs escaping\\\\too"
});
Assert.Equal(
"Good " +
"Good\\ " +
"\"Needs quotes\" " +
"\"Needs escaping\\\\\" " +
"\"Needs escaping\\\\\\\\\" " +
"\"Needs \\\"escaping\\\"\" " +
"\"Needs \\\\\\\"escaping\\\"\" " +
"\"Needs escaping\\\\\\\\too\"",
result);
}
private static string ToArguments(IReadOnlyList<string> args)
=> (string)typeof(Exe).GetTypeInfo().GetMethod("ToArguments", BindingFlags.Static | BindingFlags.NonPublic)
.Invoke(null, new object[] { args });
}
}

Просмотреть файл

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFramework>netcoreapp1.0</TargetFramework>
<RootNamespace>Microsoft.EntityFrameworkCore.Tools</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\dotnet-ef\dotnet-ef.csproj" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="Moq" Version="4.6.38-alpha" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,363 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#if NET452
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Relational.Design.Specification.Tests.TestUtilities;
using Microsoft.EntityFrameworkCore.Tools.TestUtilities;
using Xunit;
namespace Microsoft.EntityFrameworkCore.Tools
{
[Collection("OperationExecutorTests")]
public class AppDomainOperationExecutorTest
{
private IOperationExecutor CreateExecutorFromBuildResult(BuildFileResult build, string rootNamespace = null)
=> new AppDomainOperationExecutor(build.TargetPath,
build.TargetPath,
build.TargetDir,
build.TargetDir,
build.TargetDir,
rootNamespace,
environment: null);
[Fact]
public void Assembly_load_errors_are_wrapped()
{
var targetDir = AppDomain.CurrentDomain.BaseDirectory;
using (var executor = new AppDomainOperationExecutor(Assembly.GetExecutingAssembly().Location, Path.Combine(targetDir, "Unknown.dll"), targetDir, null, null, null, null))
{
Assert.Throws<WrappedException>(() => executor.GetContextTypes());
}
}
[Fact]
public void GetMigrations_filters_by_context_name()
{
using (var directory = new TempDirectory())
{
var targetDir = directory.Path;
var source = new BuildSource
{
TargetDir = targetDir,
References =
{
BuildReference.ByName("System.Diagnostics.DiagnosticSource", true),
BuildReference.ByName("System.Interactive.Async", true),
BuildReference.ByName("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"),
BuildReference.ByName("Microsoft.AspNetCore.Hosting.Abstractions", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Design", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational.Design", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Memory", true),
BuildReference.ByName("Microsoft.Extensions.Configuration.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.FileProviders.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Logging", true),
BuildReference.ByName("Microsoft.Extensions.Logging.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Options", true),
BuildReference.ByName("Remotion.Linq", true)
},
Sources = { @"
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
namespace MyProject
{
internal class Context1 : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(""Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SimpleProject.SimpleContext;Integrated Security=True"");
}
}
internal class Context2 : DbContext
{
}
namespace Migrations
{
namespace Context1Migrations
{
[DbContext(typeof(Context1))]
[Migration(""000000000000000_Context1Migration"")]
public class Context1Migration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
}
}
namespace Context2Migrations
{
[DbContext(typeof(Context2))]
[Migration(""000000000000000_Context2Migration"")]
public class Context2Migration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
}
}
}
}" }
};
var build = source.Build();
using (var executor = CreateExecutorFromBuildResult(build, "MyProject"))
{
var migrations = executor.GetMigrations("Context1");
Assert.Equal(1, migrations.Count());
}
}
}
[Fact]
public void GetContextType_works_with_multiple_assemblies()
{
using (var directory = new TempDirectory())
{
var targetDir = directory.Path;
var contextsSource = new BuildSource
{
TargetDir = targetDir,
References =
{
BuildReference.ByName("Microsoft.EntityFrameworkCore", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Design", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Logging.Abstractions", true)
},
Sources = { @"
using Microsoft.EntityFrameworkCore;
namespace MyProject
{
public class Context1 : DbContext
{
}
public class Context2 : DbContext
{
}
}" }
};
var contextsBuild = contextsSource.Build();
var migrationsSource = new BuildSource
{
TargetDir = targetDir,
References =
{
BuildReference.ByName("System.Reflection.Metadata", true),
BuildReference.ByName("Microsoft.AspNetCore.Hosting.Abstractions", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore"),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational.Design", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Configuration.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.FileProviders.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Logging", true),
BuildReference.ByName("Microsoft.Extensions.Logging.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Options", true),
BuildReference.ByPath(contextsBuild.TargetPath)
},
Sources = { @"
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
namespace MyProject
{
internal class Context3 : DbContext
{
}
namespace Migrations
{
namespace Context1Migrations
{
[DbContext(typeof(Context1))]
[Migration(""000000000000000_Context1Migration"")]
public class Context1Migration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
}
}
namespace Context2Migrations
{
[DbContext(typeof(Context2))]
[Migration(""000000000000000_Context2Migration"")]
public class Context2Migration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
}
}
}
}" }
};
var build = migrationsSource.Build();
using (var executor = CreateExecutorFromBuildResult(build, "MyProject"))
{
var contextTypes = executor.GetContextTypes();
Assert.Equal(3, contextTypes.Count());
}
}
}
[Fact]
public void AddMigration_begins_new_namespace_when_foreign_migrations()
{
using (var directory = new TempDirectory())
{
var targetDir = directory.Path;
var source = new BuildSource
{
TargetDir = targetDir,
References =
{
BuildReference.ByName("System.Diagnostics.DiagnosticSource", true),
BuildReference.ByName("System.Interactive.Async", true),
BuildReference.ByName("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"),
BuildReference.ByName("Microsoft.AspNetCore.Hosting.Abstractions", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Design", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational.Design", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Memory", true),
BuildReference.ByName("Microsoft.Extensions.Configuration.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.FileProviders.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Logging", true),
BuildReference.ByName("Microsoft.Extensions.Logging.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Options", true),
BuildReference.ByName("Remotion.Linq", true)
},
Sources = { @"
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
namespace MyProject
{
internal class MyFirstContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(""Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=MyProject.MyFirstContext"");
}
}
internal class MySecondContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(""Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=MyProject.MySecondContext"");
}
}
namespace Migrations
{
[DbContext(typeof(MyFirstContext))]
[Migration(""20151006140723_InitialCreate"")]
public class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
}
}
}" }
};
var build = source.Build();
using (var executor = CreateExecutorFromBuildResult(build, "MyProject"))
{
var artifacts = executor.AddMigration("MyMigration", /*outputDir:*/ null, "MySecondContext");
Assert.Equal(3, artifacts.Keys.Count);
Assert.True(Directory.Exists(Path.Combine(targetDir, @"Migrations\MySecond")));
}
}
}
[Fact]
public void Throws_for_no_parameterless_constructor()
{
using (var directory = new TempDirectory())
{
var targetDir = directory.Path;
var source = new BuildSource
{
TargetDir = targetDir,
References =
{
BuildReference.ByName("System.Diagnostics.DiagnosticSource", true),
BuildReference.ByName("System.Interactive.Async", true),
BuildReference.ByName("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"),
BuildReference.ByName("Microsoft.AspNetCore.Hosting.Abstractions", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Design", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational.Design", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Memory", true),
BuildReference.ByName("Microsoft.Extensions.Configuration.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.FileProviders.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Logging", true),
BuildReference.ByName("Microsoft.Extensions.Logging.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Options", true),
BuildReference.ByName("Remotion.Linq", true)
},
Sources = { @"
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
namespace MyProject
{
internal class MyContext : DbContext
{
public MyContext(DbContextOptions<MyContext> options) :base(options) {}
}
}" }
};
var build = source.Build();
using (var executor = CreateExecutorFromBuildResult(build, "MyProject"))
{
var ex = Assert.Throws<WrappedException>(
() => executor.GetMigrations("MyContext"));
Assert.Equal(
DesignStrings.NoParameterlessConstructor("MyContext"),
ex.Message);
}
}
}
}
}
#endif

Просмотреть файл

@ -0,0 +1,73 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Linq;
using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.EntityFrameworkCore.Tools.Commands;
using Xunit;
namespace Microsoft.EntityFrameworkCore.Tools
{
public class CommandsTest
{
[Fact]
public void Short_names_are_unique()
{
foreach (var command in GetCommands())
{
foreach (var group in command.Options.GroupBy(o => o.ShortName))
{
Assert.True(
group.Key == null || group.Count() == 1,
"Duplicate short names on command '" + GetFullName(command) + "': " +
string.Join("; ", group.Select(o => o.Template)));
}
}
}
private static IEnumerable<CommandLineApplication> GetCommands()
{
var app = new CommandLineApplication()
{
Name = "ef"
};
new RootCommand().Configure(app);
return GetCommands(app);
}
private static IEnumerable<CommandLineApplication> GetCommands(CommandLineApplication command)
{
var commands = new Stack<CommandLineApplication>();
commands.Push(command);
while (commands.Count != 0)
{
command = commands.Pop();
yield return command;
foreach (var subcommand in command.Commands)
{
commands.Push(subcommand);
}
}
}
private static string GetFullName(CommandLineApplication command)
{
var names = new Stack<string>();
while (command != null)
{
names.Push(command.Name);
command = command.Parent;
}
return string.Join(" ", names);
}
}
}

Просмотреть файл

@ -0,0 +1,208 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#if NET452
using System;
using System.Collections;
using System.IO;
using System.Linq;
using Microsoft.EntityFrameworkCore.Relational.Design.Specification.Tests.TestUtilities;
using Microsoft.EntityFrameworkCore.Tools.TestUtilities;
using Xunit;
namespace Microsoft.EntityFrameworkCore.Tools
{
[Collection("OperationExecutorTests")]
public class SimpleProjectTest : IClassFixture<SimpleProjectTest.SimpleProject>
{
private readonly SimpleProject _project;
public SimpleProjectTest(SimpleProject project)
{
_project = project;
}
private void AssertDefaultMigrationName(IDictionary artifacts)
=> Assert.Contains("namespace SimpleProject.Migrations", File.ReadAllText(artifacts["MigrationFile"] as string));
[Fact]
public void AddMigration()
{
var artifacts = _project.Executor.AddMigration("EmptyMigration", "CustomFolder", "SimpleContext");
Assert.NotNull(artifacts);
Assert.NotNull(artifacts["MigrationFile"]);
Assert.NotNull(artifacts["MetadataFile"]);
Assert.NotNull(artifacts["SnapshotFile"]);
Assert.True(Directory.Exists(Path.Combine(_project.TargetDir, "CustomFolder")));
Assert.Contains("namespace SimpleProject.CustomFolder", File.ReadAllText(artifacts["MigrationFile"] as string));
}
[Fact]
public void AddMigration_output_dir_relative_to_projectdir()
{
var artifacts = _project.Executor.AddMigration("EmptyMigration1", "./CustomFolder", "SimpleContext");
Assert.NotNull(artifacts);
Assert.StartsWith(Path.Combine(_project.TargetDir, "CustomFolder"), artifacts["MigrationFile"] as string);
Assert.Contains("namespace SimpleProject.CustomFolder", File.ReadAllText(artifacts["MigrationFile"] as string));
}
[Fact]
public void AddMigration_output_dir_relative_out_of_to_projectdir()
{
var artifacts = _project.Executor.AddMigration("EmptyMigration1", "../CustomFolder", "SimpleContext");
Assert.NotNull(artifacts);
Assert.StartsWith(Path.GetFullPath(Path.Combine(_project.TargetDir, "../CustomFolder")), artifacts["MigrationFile"] as string);
AssertDefaultMigrationName(artifacts);
}
[Fact]
public void AddMigration_output_dir_absolute_path_in_project()
{
var outputDir = Path.Combine(_project.TargetDir, "A/B/C");
var artifacts = _project.Executor.AddMigration("EmptyMigration1", outputDir, "SimpleContext");
Assert.NotNull(artifacts);
Assert.Equal(Path.Combine(outputDir, Path.GetFileName(artifacts["MigrationFile"] as string)), artifacts["MigrationFile"]);
Assert.Contains("namespace SimpleProject.A.B.C", File.ReadAllText(artifacts["MigrationFile"] as string));
}
[Fact]
public void AddMigration_output_dir_absolute_path_outside_project()
{
var outputDir = Path.GetTempPath();
var artifacts = _project.Executor.AddMigration("EmptyMigration1", outputDir, "SimpleContext");
Assert.NotNull(artifacts);
Assert.StartsWith(outputDir, artifacts["MigrationFile"] as string);
AssertDefaultMigrationName(artifacts);
}
[Theory]
[InlineData("")]
[InlineData(" ")]
[InlineData(null)]
public void AddMigration_handles_empty_output_dir(string outputDir)
{
var artifacts = _project.Executor.AddMigration("EmptyMigration2", outputDir, "SimpleContext");
Assert.NotNull(artifacts);
Assert.StartsWith(Path.Combine(_project.TargetDir, "Migrations"), artifacts["MigrationFile"] as string);
AssertDefaultMigrationName(artifacts);
}
[Fact]
public void ScriptMigration()
{
var sql = _project.Executor.ScriptMigration(null, "InitialCreate", false, "SimpleContext");
Assert.NotEmpty(sql);
}
[Fact]
public void GetContextType()
{
var contextTypeName = _project.Executor.GetContextType("SimpleContext");
Assert.StartsWith("SimpleProject.SimpleContext, ", contextTypeName);
}
[Fact]
public void GetContextTypes()
{
var contextTypes = _project.Executor.GetContextTypes();
Assert.Equal(1, contextTypes.Count());
}
[Fact]
public void GetMigrations()
{
var migrations = _project.Executor.GetMigrations("SimpleContext");
Assert.Equal(1, migrations.Count());
}
[Fact]
public void GetContextInfo_returns_connection_string()
{
var info = _project.Executor.GetContextInfo("SimpleContext");
Assert.Equal(@"(localdb)\MSSQLLocalDB", info["DataSource"]);
Assert.Equal("SimpleProject.SimpleContext", info["DatabaseName"]);
}
public class SimpleProject : IDisposable
{
private readonly TempDirectory _directory = new TempDirectory();
public SimpleProject()
{
var source = new BuildSource
{
TargetDir = TargetDir,
References =
{
BuildReference.ByName("System.Diagnostics.DiagnosticSource", true),
BuildReference.ByName("System.Interactive.Async", true),
BuildReference.ByName("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"),
BuildReference.ByName("Microsoft.AspNetCore.Hosting.Abstractions", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Design", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational.Design", true),
BuildReference.ByName("Microsoft.EntityFrameworkCore.SqlServer", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Caching.Memory", true),
BuildReference.ByName("Microsoft.Extensions.Configuration.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection", true),
BuildReference.ByName("Microsoft.Extensions.DependencyInjection.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.FileProviders.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Logging", true),
BuildReference.ByName("Microsoft.Extensions.Logging.Abstractions", true),
BuildReference.ByName("Microsoft.Extensions.Options", true),
BuildReference.ByName("Remotion.Linq", true)
},
Sources = { @"
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
namespace SimpleProject
{
internal class SimpleContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(""Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SimpleProject.SimpleContext;Integrated Security=True"");
}
}
namespace Migrations
{
[DbContext(typeof(SimpleContext))]
[Migration(""20141010222726_InitialCreate"")]
public class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
}
}
}
}" }
};
var build = source.Build();
Executor = new AppDomainOperationExecutor(build.TargetPath,
build.TargetPath,
build.TargetDir,
build.TargetDir,
build.TargetDir,
"SimpleProject",
null);
}
public string TargetDir => _directory.Path;
internal IOperationExecutor Executor { get; }
public void Dispose()
{
Executor.Dispose();
_directory.Dispose();
}
}
}
}
#endif

Просмотреть файл

@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using IOPath = System.IO.Path;
namespace Microsoft.EntityFrameworkCore.Tools.TestUtilities
{
public class TempDirectory : IDisposable
{
public TempDirectory()
{
Path = IOPath.Combine(IOPath.GetTempPath(), IOPath.GetRandomFileName());
Directory.CreateDirectory(Path);
}
public string Path { get; }
public void Dispose()
=> Directory.Delete(Path, recursive: true);
}
}

Просмотреть файл

@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<TargetFrameworks>net452;netcoreapp1.1</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' != 'Windows_NT'">netcoreapp1.1</TargetFrameworks>
<RootNamespace>Microsoft.EntityFrameworkCore.Tools</RootNamespace>
<!-- TODO: Remove when Microsoft/vstest#428 is fixed. -->
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\src\EFCore.Relational.Design.Specification.Tests\TestUtilities\BuildFileResult.cs" />
<Compile Include="..\..\src\EFCore.Relational.Design.Specification.Tests\TestUtilities\BuildReference.cs" />
<Compile Include="..\..\src\EFCore.Relational.Design.Specification.Tests\TestUtilities\BuildSource.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ef\ef.csproj" />
<ProjectReference Include="..\..\src\EFCore.Design\EFCore.Design.csproj" />
<ProjectReference Include="..\..\src\EFCore.SqlServer\EFCore.SqlServer.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="1.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
</ItemGroup>
</Project>

Просмотреть файл

@ -10,7 +10,7 @@
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="EnvDTE" #>
<#
var model = LoadResources((string)Session["ResourceFile"]);
var model = LoadResources();
#>
// <auto-generated />
@ -24,7 +24,7 @@ namespace <#= model.Namespace #>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public static class <#= model.Class #>
<#= model.AccessModifier #> static class <#= model.Class #>
{
private static readonly ResourceManager _resourceManager
= new ResourceManager("<#= model.ResourceName #>", typeof(<#= model.Class #>).GetTypeInfo().Assembly);
@ -76,13 +76,19 @@ namespace <#= model.Namespace #>
}
}
<#+
ResourceFile LoadResources(string resourceFile)
ResourceFile LoadResources()
{
var result = new ResourceFile();
if (Session.ContainsKey("AccessModifier"))
{
result.AccessModifier = (string)Session["AccessModifier"];
};
var services = (IServiceProvider)Host;
var dte = (DTE)services.GetService(typeof(DTE));
var resourceFile = (string)Session["ResourceFile"];
if (!Path.IsPathRooted(resourceFile))
{
resourceFile = Host.ResolvePath(resourceFile);
@ -139,6 +145,7 @@ namespace <#= model.Namespace #>
class ResourceFile
{
public string Namespace { get; set; }
public string AccessModifier { get; set; } = "public";
public string Class { get; set; }
public string ResourceName { get; set; }
public IEnumerable<Resource> Resources { get; set; }