Операция не поддерживается в этой платформе при создании конфигурации NHibernate из powershell - PullRequest
1 голос
/ 02 марта 2020

Я пытаюсь добавить миграции в проект, который использует Fluent NHibernate для вызова базы данных. Проблема в том, что я хотел сделать это в стиле Entity Framework, добавить миграции или применить их из консоли диспетчера пакетов.

Для этого я использовал FluentMigrator и FluentMigrator.NHibernate , и после портирования второго на. Net Standard и проверки того, что все идет хорошо, я начал работать над сценарием Powershell, который запускает «Add-Migration» из пакета консоль менеджера.

Проблема в том, что когда программа пытается создать конфигурацию NHibernate, она выдает исключение TypeInitializationException для NHibernate.NHibernateLogger. И InnerException говорит:

   System.TypeInitializationException: The type initializer for 'NHibernate.Cfg.Environment' threw an exception. 
---> System.TypeInitializationException: The type initializer for 'NHibernate.NHibernateLogger' threw an exception. 
---> System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize 
---> System.PlatformNotSupportedException: Operation is not supported on this platform.
   at System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig)
   at System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig)
   at System.Configuration.ClientConfigurationHost.get_ConfigPaths()
   at System.Configuration.ClientConfigurationHost.GetStreamName(String configPath)
   at System.Configuration.ClientConfigurationHost.get_IsAppConfigHttp()
   at System.Configuration.Internal.DelegatingConfigHost.get_IsAppConfigHttp()
   at System.Configuration.ClientConfigurationSystem..ctor()
   at System.Configuration.ConfigurationManager.EnsureConfigurationSystem()
   --- End of inner exception stack trace ---
   at System.Configuration.ConfigurationManager.EnsureConfigurationSystem()
   at System.Configuration.ConfigurationManager.PrepareConfigSystem()
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.Configuration.ConfigurationManager.get_AppSettings()
   at NHibernate.NHibernateLogger.GetNhibernateLoggerClass()
   at NHibernate.NHibernateLogger..cctor()
   --- End of inner exception stack trace ---
   at NHibernate.NHibernateLogger.For(Type type)
   at NHibernate.Cfg.Environment..cctor()
   --- End of inner exception stack trace ---
   at NHibernate.Cfg.Configuration.Reset()
   at NHibernate.Cfg.Configuration..ctor(SettingsFactory settingsFactory)
   at NHibernate.Cfg.Configuration..ctor()
   at JobsEngine.Migrations.BaseConfig.MigrationsConfiguration.GetConfiguration()

Это вызывается при создании конфигурации с использованием NHibernate, например так:

protected override Configuration GetConfiguration()
    {
        Configuration config = new Configuration(); //this is what throws the exception
        config = Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2012.Dialect<MsSql2012Dialect>())
            .Mappings(x => x.FluentMappings.AddFromAssembly(MigrationAssembly))
            .BuildConfiguration();
        return config;
    }

И поиск информации для этого «Операция не поддерживается на этой платформе «Исключение, кажется, что бросает именно эту часть кода:

exeAssembly = Assembly.GetEntryAssembly();

if (exeAssembly == null)
   throw new PlatformNotSupportedException();

в этой строке corefx .

Я понимаю, что это не так работать, потому что я запускаю его из скрипта Powershell, получая сборку и т. д., чтобы не было «входной сборки» (GetEntryAssembly возвращает ноль). Если я запускаю из консольного проекта или модульного теста, он работает отлично. Есть ли обходной путь или решение этой проблемы? Я хотел бы иметь возможность запускать его из скрипта powershell.

Я должен сказать, что все библиотеки, на которые есть ссылки, используются (или должны использовать). Net standard.

EDIT: соответствующая часть сценария powershell, используемая для запуска этого:

$migration = [FluentMigrator.NHibernate.PSEntryPoint]::Generate($targetPath, $MigrationName)

Где $ MigrationName - строка, а targetPath - путь сборки, в которой выполняются миграции, после того, как она была построена с использованием EnvDTE :

$configuration = $DTE.Solution.SolutionBuild.ActiveConfiguration.Name

$DTE.Solution.SolutionBuild.BuildProject($configuration, $project.UniqueName, $true)

Где PSEntryPoint:

public static class PSEntryPoint
{
    public static object Generate(string targetPath, string migrationName)
    {
         MigrationConfigurationBase migrationConfiguration = GetMigrationConfigFromAssembly(targetPath);
        return migrationConfiguration.Generate(migrationName, targetPath);
    }

private static MigrationConfigurationBase GetMigrationConfigFromAssembly(string assemblyName)
    {
        var assembly = Assembly.LoadFrom(assemblyName);
        var migrationConfigTypes = assembly.GetTypes().Where(x => x != null && x.IsClass && !x.IsAbstract
            && typeof(MigrationConfigurationBase).IsAssignableFrom(x)).ToList();

        var migrationConfig = Activator.CreateInstance(migrationConfigTypes.First()) as MigrationConfigurationBase;

        return migrationConfig;
    }

В целом это работает, создается экземпляр конфигурации миграции, запускается «Генерация», но когда он попадает в новую конфигурацию из NHibernate выбрасывает платформу, которая не поддерживается.

1 Ответ

0 голосов
/ 05 марта 2020

Проблема именно в том, что вы знаете. Вы запускаете скрипт C# code * PowerShell. Я попробовал несколько обходных путей и, к сожалению, я не мог найти какие-либо решения для этого. Но я рекомендую начать использовать C# Scripting вместо PowerShell. Например, посмотрите на следующий код:

Сначала установите глобальный инструмент do tnet -script.

dotnet tool install -g dotnet-script

Создайте файл csx или используйте dotnet script init для создания сценария .

// filename: main.csx

#r "nuget: FluentMigrator, 3.2.1"
#r "nuget: FluentMigrator.Runner, 3.2.1"
#r "nuget: FluentMigrator.NHibernate, 1.0.0.17"
#r "nuget: NHibernate, 5.2.7"
#r "nuget: Fluent.NHibernate, 2.1.2"

using FluentMigrator;
using FluentMigrator.Runner;
using FluentMigrator.Runner.Processors;
using FluentMigrator.NHibernate;
using NHibernate;

var config = new Configuration();
config = Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2012.Dialect<MsSql2012Dialect>())
    .Mappings(x => x.FluentMappings.AddFromAssembly(MigrationAssembly))
    .BuildConfiguration();

И внутри терминала / консоли:

dotnet script main.csx

Конечно, код, который я написал, был просто для того, чтобы доказать, что вы можете получить доступ к Assembly.GetEntryAssembly внутри скриптов CSharp.

Честно говоря, такие скрипты CSharp лучше выполнять, их легко отлаживать, а также проще запускать в них C# сборок.

Если вам интереснее C# Сценарии, вы можете прочитать мою статью здесь: Руководство автостопом по C# сценариям

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...