【问题标题】:Access DB context through SignalR Core通过 SignalR Core 访问数据库上下文
【发布时间】:2018-06-16 06:45:30
【问题描述】:

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

谢谢。

以下是相关代码:

Startup.cs

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();
} 

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

MyHub.cs

using (PlayerContext dbContext = new PlayerContext(/* Singleton needs to go here */))
{
    // do database stuff
} 

【问题讨论】:

  • 你能告诉我们你的代码吗?
  • 我添加了它。使用这样的上下文只是我可以做到这一点的一种方式,我对任何事情都持开放态度,我只需要从我的 Hub 类内部访问数据库(最好不直接执行 SQL)。

标签: c# signalr dbcontext signalr-hub asp.net-core-signalr


【解决方案1】:

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

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

using (var dbContextScope = dbContextScopeFactory.Create(options))
{
    //do database stuff
    dbContextScope.SaveChanges();
}

【讨论】:

【解决方案2】:

我用 .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
      }
}

【讨论】:

  • 完美运行,非常简单,非常感谢!
  • @Katori 很高兴听到我能帮上忙 :)
【解决方案3】:

似乎仍然没有记录访问范围服务。但是查看源代码我们可以看到DefaultHubDispatcher every invocation 上创建范围和集线器实例。这意味着我们可以使用DbContext 和其他范围服务,就像我们在asp.net core 控制器中使用的那样。

新的DbContext 实例在每次调用集线器方法时被注入到集线器构造函数中。调用完成后,DbContext 被释放。

Startup.cs:

services.AddDbContext<PlayerContext>(
    options => { options.UseSqlServer(Configuration.GetConnectionString("Default")); },
    ServiceLifetime.Scoped
);

枢纽:

public class PlayerHub
{
    private readonly PlayerContext _dbContext;
    public PlayerHub(PlayerContext dbContext)
    {
       _dbContext = dbContext;
    }
    // using _dbContext 
}

【讨论】:

    【解决方案4】:

    这在 .net Core 3.1 中对我有用,带有 Entity Framework Core 和 SignalR。我不必在启动时添加任何东西(实际上在 3.1 中默认启动中不包含连接服务)。一切都在 hub 和 appsettings.json 中完成。

    应用设置:

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*",
      "ConnectionStrings": {
        "ConStr": "Data Source=.\\sqlexpress;Initial Catalog=ReactUserTasks;Integrated Security=true;"
      }
    }
    

    集线器: 调用 appsettings 中设置的“ConStr”连接。

    public class MyHub : Hub
    {
        private string _conn;
    
        public MyHub(IConfiguration configuration)
        {
            _conn = configuration.GetConnectionString("ConStr");
        } 
    

    然后在MyHub 中设置使用连接的方法。

    public List<Items> GetTasks()
    {
        var db = new ItemRepository(_conn);
        return db.GetTasks();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-23
      • 1970-01-01
      • 2012-09-23
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多