Net Core Worker Windows 服务中的 EF Core DBContext

EF Core DBContext inside Net Core Worker Windows service

我想要实现的是编写一个简单的 .net 核心后台工作者(.net 核心 3.1),我将数据写入 SQL 服务器数据库(通过 EF Core 3.1),而这个工作者是 运行宁作为 windows 服务。

当我 运行 来自 Visual Studio 2019 的以下代码时,一切正常,但是当我发布(目标 win-x64)并将 .exe 注册为我的 win10 机器上的服务时,我得到以下异常:

Microsoft.Data.SqlClient is not supported on this platform.

对导致此问题的原因以及如何解决有任何想法吗?

Program.cs

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Soteria.Common.Database;

namespace Soteria.Service
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args)
        {
            var host = Host.CreateDefaultBuilder(args)
                .UseWindowsService()
                .ConfigureServices((hostContext, services) =>
                {
                    var optionsBuilder = new DbContextOptionsBuilder<SoteriaDbContext>();
                    optionsBuilder.UseSqlServer("Server=.\SQLEXPRESS;Database=Soteria;Trusted_Connection=True;");//,
                    services.AddScoped<SoteriaDbContext>(s => new SoteriaDbContext(optionsBuilder.Options));

                    services.AddHostedService<Worker>();
                });

            return host;
        }
    }
}

Worker.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Soteria.Common.Database;
using Soteria.Common.Messaging;
using Soteria.Common.Models;

namespace Soteria.Service
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private readonly IServiceScopeFactory _serviceScopeFactory;

        public Worker(ILogger<Worker> logger, IServiceScopeFactory serviceScopeFactory)
        {
            _logger = logger;
            _serviceScopeFactory = serviceScopeFactory;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                using var scope = _serviceScopeFactory.CreateScope();

                var dbContext = scope.ServiceProvider.GetRequiredService<SoteriaDbContext>();

                dbContext.Tests.Add(new Test() {Date = DateTime.Now});
                dbContext.SaveChanges();

                await Task.Delay(1000, stoppingToken);               
            }
        }  
    }
}

SoteriaDbContext.cs

using Microsoft.EntityFrameworkCore;
using Soteria.Common.Models;

namespace Soteria.Common.Database
{
    public class SoteriaDbContext: DbContext
    {
        public SoteriaDbContext(DbContextOptions<SoteriaDbContext> options)
            : base(options)
        {
        }

        public DbSet<Test> Tests { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {            
            modelBuilder.Entity<Test>().ToTable("Tests");
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.EnableSensitiveDataLogging(true);
        }
    }
}

Test.cs

using System;

namespace Soteria.Common.Models
{
    public class Test
    {
        public int? Id { get; set; }
        public DateTime Date { get; set; }
    }
}

Tests.sql

CREATE TABLE [dbo].[Tests]
(
    [Id] INT NOT NULL PRIMARY KEY IDENTITY, 
    [Date] DATETIME NOT NULL
)

我必须安装 win-x64 文件夹的已发布源,而不是 "publish" 文件夹才能使它真正起作用。即使我的目标运行时是 win-x64,这也会让我期望发布的结果会在 "publish" 文件夹中。

Release folder structure and confusing publish folder