Dot-Net-Core

Net Core Worker Windows 服務中的 EF Core DBContext

  • July 17, 2020

我想要實現的是編寫一個簡單的.net core 後台工作程序(.net core 3.1),當這個工作程序作為 Windows 服務執行時,我將數據寫入 SQL Server 數據庫(通過 EF Core 3.1)。

當我從 Visual Studio 2019 執行以下程式碼時,一切正常,但是當我發布(目標 win-x64)並將 .exe 註冊為我的 win10 機器上的服務時,我收到以下異常:

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

關於導致此問題的原因以及如何解決的任何想法?

程序.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;
       }
   }
}

工人.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);
       }
   }
}

測試.cs

using System;

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

測試.sql

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

我必須安裝 win-x64 文件夾的已發布源,而不是“發布”文件夾才能使其真正起作用。即使我的目標執行時是 win-x64,這也會導致我期望發布的結果會在“發布”文件夾中。

發布文件夾結構和混淆發布文件夾

引用自:https://stackoverflow.com/questions/59749330