我正在尝试向使用Fluent NHibernate调用数据库的项目添加迁移。问题是我想以实体框架样式进行操作,从“程序包管理器控制台”添加迁移或使用迁移。
为此,我使用了FluentMigrator和FluentMigrator.NHibernate,然后将第二个移植到.Net Standard,并检查一切运行正常之后,我开始研究Powershell脚本,该脚本将启动“ Add-从包管理器控制台迁移。
问题是,当程序尝试构建NHibernate配置时,它将为NHibernate.NHibernateLogger引发TypeInitializationException。 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();
我知道这是行不通的,因为我是从Powershell脚本启动它并获取程序集的,所以没有“入口程序集”(GetEntryAssembly返回null)。如果我是从控制台项目或单元测试启动的,那么它将非常完美。是否有解决方法或解决方案?我想保持从powershell脚本启动它的能力。
我不得不说,这里引用的所有库都在使用(或应该使用).Net标准。
编辑:用于启动此程序的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;
}
[通常,它创建迁移配置的一个实例,启动“ Generate”,但是当它从NHibernate转到新的Configuration时,它抛出了不受支持的平台。
问题正是您所知道的。您正在使用PowerShell
脚本运行C#代码。我尝试了几种解决方法,但不幸的是,我找不到任何解决方案。但是,我建议开始使用C#脚本而不是PowerShell。例如,请看下面的代码:
首先,安装dotnet-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
当然,我编写的代码只是为了证明您可以在CSharp脚本中访问Assembly.GetEntryAssembly
。
老实说,最好执行这种CSharp脚本,它们易于调试,并且在其中运行C#程序集也更容易。
如果您对C#脚本更加好奇,可以在这里阅读我的文章:Hitchhiker’s Guide to the C# scripting