通过SignalR Core访问数据库上下文

Kat*_*ori 1 c# dbcontext signalr signalr-hub asp.net-core-signalr

我正在使用AspNetCore.SignalR,并且需要有关如何通过集线器访问SQL Server数据库的建议。有关此的资源不多。我知道如何添加一个单例,但以后不知道如何访问它。如何访问使用集线器任务内Startup.cs中的Configuration.GetConnectionString定义的数据库上下文?

谢谢。

以下是相关代码:

启动文件

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
        });


    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    DbContextOptionsBuilder<PlayerContext> PlayerContextOptions = new DbContextOptionsBuilder<PlayerContext>();
    PlayerContextOptions.UseSqlServer(Configuration.GetConnectionString("Default"));
    services.AddSingleton(PlayerContextOptions.Options);

    services.AddDbContext<PlayerContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Default")));



    services.AddCors(options => options.AddPolicy("CorsPolicy",
        builder =>
        {
            builder.AllowAnyMethod().AllowAnyHeader()
            .AllowCredentials();
            }));

    services.AddSignalR();
} 
Run Code Online (Sandbox Code Playgroud)

但是我根本不知道该在Hub文件中做什么。我什至不知道从哪里开始。我添加了单例,但是我不知道如何在我的中心文件中访问它。这是我想做的,但是我愿意做一个更好的方法:

MyHub.cs

using (PlayerContext dbContext = new PlayerContext(/* Singleton needs to go here */))
{
    // do database stuff
} 
Run Code Online (Sandbox Code Playgroud)

Dar*_*rem 7

我用 .NET Core 3 测试了这段代码!

您必须将 DBContext 添加到 DI,以便您可以从 Hub 的构造函数中获取它。

public class MyHub
{
      private PlayerContext dbContext;
 
      public MyHub(PlayerContext dbContext)
      {
           this.dbContext = dbContext;
      }

      public void YourMethod()
      {
           //call the dbContext here by Dot Notaition
      }
}
Run Code Online (Sandbox Code Playgroud)


Den*_*iss 5

在SignalR集线器上使用依赖项注入来注入EF DbContext是一个错误的选择,因为SignalR集线器本身是Singleton,并且不应具有生命周期较短的依赖项,您最终会得到警告。这意味着,您不能使用PerRequest / Transient生存期作用域来注册DbContext,而只能使用Singleton。将DbContext注册为Singleton是一个非常糟糕的选择。创建新上下文并不昂贵,但是具有单例上下文的中心将在一段时间后成倍增长。

我建议将DbContextFactory用于Hub类,在您的Hub中从工厂询问新的DbContext并将其放在using语句中。您还可以将工厂本身注册为Singleton,并更加清楚集线器构造函数中的依赖性。

using (var dbContextScope = dbContextScopeFactory.Create(options))
{
    //do database stuff
    dbContextScope.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

  • 从 .Net 5 开始,情况似乎不再如此。集线器是暂时的:https://docs.microsoft.com/en-us/aspnet/core/signalr/hubs?view=aspnetcore-5.0#create-and-use-hubs (3认同)