我正在使用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
}
答案 0 :(得分:4)
使用对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();
}
答案 1 :(得分:2)
您必须将您的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
}
}
答案 2 :(得分:0)
似乎仍未记录访问范围服务的信息。但是查看源代码,我们可以看到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
}
答案 3 :(得分:0)
这在带有 Entity Framework Core 和 SignalR 的 .net Core 3.1 中对我有用。我没有在启动时添加任何东西(实际上在 3.1 中默认启动中没有包含连接服务)。一切都在中心和 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();
}