Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Windows服务中使用EF核心迁移?_C#_Entity Framework_.net Core_Entity Framework Core_Windows Services - Fatal编程技术网

C# 如何在Windows服务中使用EF核心迁移?

C# 如何在Windows服务中使用EF核心迁移?,c#,entity-framework,.net-core,entity-framework-core,windows-services,C#,Entity Framework,.net Core,Entity Framework Core,Windows Services,您好,我正在尝试实现一个需要EF核心迁移的Windows服务。以下是我的DbContext继承器: public sealed class ExchangeContext : DbContext { public const string SchemaName = "Exchange"; public ExchangeContext(DbContextOptions<ExchangeContext> options) :

您好,我正在尝试实现一个需要EF核心迁移的Windows服务。以下是我的DbContext继承器:

public sealed class ExchangeContext : DbContext
{
    public const string SchemaName = "Exchange";
    
    public ExchangeContext(DbContextOptions<ExchangeContext> options)
        : base(options)
    {
    }
    
    ...
    
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder
            .ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
    }
}
公共密封类ExchangeContext:DbContext
{
public const string SchemaName=“Exchange”;
公共ExchangeContext(DbContextOptions选项)
:基本(选项)
{
}
...
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
建模者
.ApplyConfigurationsFromAssembly(Assembly.getExecutionGassembly());
}
}
我的Program.cs文件如下所示:

public static class Program
{
    public static void Main(string[] args) =>
        Host
            .CreateDefaultBuilder(args)
            .ConfigureServices((_, services) =>
            {
                var configuration = services 
                    .BuildServiceProvider() 
                    .GetRequiredService<IConfiguration>();

                services
                    .AddApplicationServices()
                    .AddInfrastructureServices(configuration);
            })
            .UseWindowsService() 
            .Build() 
            .Run();
}
公共静态类程序
{
公共静态void Main(字符串[]参数)=>
主办
.CreateDefaultBuilder(args)
.ConfigureServices((u,services)=>
{
var配置=服务
.BuildServiceProvider()
.GetRequiredService();
服务
.AddApplicationServices()
.AddInfrastructureServices(配置);
})
.UseWindowsService()
.Build()
.Run();
}
我使用以下逻辑注册DbContext:

...

.AddDatabaseContext<ExchangeContext>(
                    configuration,
                    DatabaseProvider.SqlServer,
                    false,
                    ExchangeContextConnectionStringSectionKey,
                    Assembly.GetExecutingAssembly().FullName)

...

namespace AsCore.Infrastructure.Persistence.EntityFrameworkCore
{
    public static class EntityFrameworkCoreConfiguration
    {
        private const string SqlServerTag = "SqlServerConnection";
        private const string PostgreSQLTag = "PostgreSQLConnection";
        
        public static IServiceCollection AddDatabaseContext<TContext>(this IServiceCollection services,
            IConfiguration configuration,
            DatabaseProvider provider,
            bool useHealthCheck,
            string connectionStringSectionName,
            string migrationAssemblyName = null) where TContext : DbContext
        {
            var connectionString = configuration
                .GetConnectionString(connectionStringSectionName);
            
            var databaseContextOptionsAction = CreateContextOptions(provider,
                connectionString,
                migrationAssemblyName);
            
            return services
                .AddDbContext<TContext>(databaseContextOptionsAction)
                .ConfigureHealthChecks<TContext>(useHealthCheck,
                    provider,
                    connectionString);
        }
        
        public static IApplicationBuilder UseMigrationsOfContext<TContext>(this IApplicationBuilder applicationBuilder)
            where TContext : DbContext
        {
            using var serviceScope = applicationBuilder
                .ApplicationServices
                .CreateScope();

            var databaseContext = serviceScope
                .ServiceProvider
                .GetService<TContext>();

            var isInvalid = databaseContext is null;

            if (isInvalid)
            {
                var errorMessage =
                    $"{nameof(UseMigrationsOfContext)}: {typeof(TContext).FullName}";

                throw new ArgumentException(errorMessage);
            }

            databaseContext
                .Database
                .Migrate();

            return applicationBuilder;
        }

        private static Action<DbContextOptionsBuilder> CreateContextOptions(DatabaseProvider provider,
            string connectionString,
            string migrationAssemblyName = null) =>
                provider switch
                {
                    DatabaseProvider.SqlServer => migrationAssemblyName != null
                        ? (Action<DbContextOptionsBuilder>) (optionsBuilder => optionsBuilder
                            .UseSqlServer(connectionString,
                                sqlServerOptionsBuilder =>
                                    sqlServerOptionsBuilder.MigrationsAssembly(migrationAssemblyName)))
                        : (DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlServer(connectionString),
                    DatabaseProvider.PostgreSQL => migrationAssemblyName != null
                        ? (Action<DbContextOptionsBuilder>) (optionsBuilder => optionsBuilder
                            .UseNpgsql(connectionString,
                                postgresOptionsBuilder =>
                                    postgresOptionsBuilder.MigrationsAssembly(migrationAssemblyName)))
                        : (DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseNpgsql(connectionString),
                    _ => throw new ArgumentOutOfRangeException(nameof(DatabaseProvider))
                };

        private static IServiceCollection ConfigureHealthChecks<TContext>(this IServiceCollection services,
            bool useHealthCheck,
            DatabaseProvider provider,
            string connectionString) where TContext : DbContext
        {
            if (!useHealthCheck)
            {
                return services;
            }

            return services
                .AddDatabaseHealthChecks<TContext>(
                    provider,
                    connectionString);
        }

        private static IServiceCollection AddDatabaseHealthChecks<TContext>(this IServiceCollection services,
            DatabaseProvider provider,
            string connectionString) where TContext : DbContext =>
                provider switch
                {
                    DatabaseProvider.SqlServer => services
                        .AddHealthChecks()
                        .AddSqlServer(connectionString,
                            name: typeof(TContext).FullName,
                            tags: new[] { SqlServerTag })
                        .Services,
                    DatabaseProvider.PostgreSQL => services
                        .AddHealthChecks()
                        .AddNpgSql(connectionString,
                            name: typeof(TContext).FullName,
                            tags: new[] { PostgreSQLTag })
                        .Services,
                    _ => throw new ArgumentOutOfRangeException(nameof(DatabaseProvider))
                };
    }
}
。。。
.AddDatabaseContext(
配置
DatabaseProvider.SqlServer,
假,,
ExchangeContextConnectionStringSectionKey,
Assembly.GetExecutionGassembly().FullName)
...
命名空间AsCore.Infrastructure.Persistence.EntityFrameworkCore
{
公共静态类EntityFrameworkCoreConfiguration
{
私有常量字符串SqlServerTag=“SqlServerConnection”;
私有常量字符串PostgreSQLTag=“PostgreSQLConnection”;
公共静态IServiceCollection AddDatabaseContext(此IServiceCollection服务,
i配置配置,
数据库提供者,
布尔使用健康检查,
字符串连接StringSectionName,
字符串migrationAssemblyName=null),其中TContext:DbContext
{
var connectionString=配置
.GetConnectionString(ConnectionString部分名称);
var DatabaseContextOptions操作=CreateContextOptions(提供程序,
连接字符串,
迁移组装名称);
回程服务
.AddDbContext(DatabaseContextOptions操作)
.配置HealthChecks(使用HealthCheck,
供应商,
连接字符串);
}
公共静态IApplicationBuilder使用上下文迁移(此IApplicationBuilder应用程序生成器)
其中TContext:DbContext
{
使用var serviceScope=applicationBuilder
.应用程序服务
.CreateScope();
var-databaseContext=serviceScope
.服务提供者
.GetService();
var isInvalid=数据库上下文为空;
如果(isInvalid)
{
var错误消息=
$“{nameof(UseMigrationsOfContext)}:{typeof(TContext.FullName}”;
抛出新的ArgumentException(errorMessage);
}
数据库上下文
数据库
.Migrate();
返回applicationBuilder;
}
专用静态操作CreateContextOptions(数据库提供程序,
字符串连接字符串,
字符串迁移AssemblyName=null)=>
提供者交换机
{
DatabaseProvider.SqlServer=>migrationAssemblyName!=null
?(操作)(选项生成器=>选项生成器
.UseSqlServer(连接字符串,
sqlServerOptionsBuilder=>
sqlServerOptionsBuilder.MigrationsAssembly(migrationAssemblyName)))
:(DBContextOptions Builder Options Builder)=>Options Builder.UseSqlServer(connectionString),
DatabaseProvider.PostgreSQL=>migrationAssemblyName!=null
?(操作)(选项生成器=>选项生成器
.UseNpgsql(连接字符串,
postgresOptionsBuilder=>
postgresOptionsBuilder.migrationassembly(migrationAssemblyName)))
:(DBContextOptions Builder Options Builder)=>Options Builder.UseNpgsql(connectionString),
_=>抛出新ArgumentOutOfRangeException(nameof(DatabaseProvider))
};
专用静态IServiceCollection配置HealthChecks(此IServiceCollection服务,
布尔使用健康检查,
数据库提供者,
字符串连接字符串),其中TContext:DbContext
{
如果(!useHealthCheck)
{
返回服务;
}
回程服务
.AddDatabaseHealthChecks(
供应商,
连接字符串);
}
专用静态IServiceCollection AddDatabaseHealthChecks(此IServiceCollection服务,
数据库提供者,
字符串连接字符串),其中TContext:DbContext=>
提供者交换机
{
DatabaseProvider.SqlServer=>services
.AddHealthChecks()
.AddSqlServer(连接字符串,
名称:typeof(TContext).FullName,
标记:新[]{SqlServerTag})
.服务,
DatabaseProvider.PostgreSQL=>services
.AddHealthChecks()
.AddNpgSql(连接字符串,
N
public class ExchangeContextFactory : IDesignTimeDbContextFactory<ExchangeContext>
{
    public ExchangeContext CreateDbContext(string[] args)
    {
        var appSettingsPath = Path.Combine(Directory.GetCurrentDirectory(), "relative-path-to-your-appsettings-file");

        var configuration = new ConfigurationBuilder()
            .SetBasePath(appSettingsPath)
            .AddJsonFile("appsettings.json")
            .Build();

        var builder = new DbContextOptionsBuilder<ExchangeContext>();
        builder.UseSqlServer(
            configuration
                .GetConnectionString("SqlServer") // In your case, the section referring to "ExchangeContextConnectionStringSectionKey"
        );

        return new ExchangeContext(builder.Options);
    }
}
dotnet ef migrations add InitialCreate --context ExchangeContext --project ExchangeContextProjectName