通过 SignalR Core 访问数据库上下文
Access DB context through SignalR Core
我正在使用 AspNetCore.SignalR,我需要有关如何通过集线器访问 SQL 服务器数据库的建议。关于这方面的资源并不多。我知道如何添加单例,但我不知道以后如何访问它。如何访问在 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();
}
但我根本不知道要在我的中心文件中做什么。我什至不知道从哪里开始。我添加了单例,但我不知道如何在我的中心文件中访问它。这是我想做的,但我愿意接受更好的方法:
MyHub.cs
using (PlayerContext dbContext = new PlayerContext(/* Singleton needs to go here */))
{
// do database stuff
}
我用 .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
}
}
使用 SignalR hub 上的依赖注入来注入 EF DbContext 是一个错误的选择,因为 SignalR hub 本身是一个 Singleton,不应该有较低生命周期的依赖,你最终会收到警告。这意味着,您不能将 DbContext 注册到 PerRequest/Transient 生命周期范围,只能使用单例。将 DbContext 注册为 Singleton 是一个非常糟糕的选择。创建新的上下文并不昂贵,但是您的具有单例上下文的集线器将在一段时间后呈指数增长。
我建议使用 Hub 的 DbContextFactory 类,在你的 hub 中从工厂请求新的 DbContext 并将其放入 using 语句。您还可以将工厂本身注册为单例,并使集线器构造函数中的依赖关系更加清晰。
using (var dbContextScope = dbContextScopeFactory.Create(options))
{
//do database stuff
dbContextScope.SaveChanges();
}
似乎仍然没有记录访问范围内的服务。但是查看源代码我们可以看到 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
}
这在 .net Core 3.1 中对我有用 Entity Framework Core 和 SignalR。我不必向启动添加任何内容(事实上,在 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();
}
我正在使用 AspNetCore.SignalR,我需要有关如何通过集线器访问 SQL 服务器数据库的建议。关于这方面的资源并不多。我知道如何添加单例,但我不知道以后如何访问它。如何访问在 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();
}
但我根本不知道要在我的中心文件中做什么。我什至不知道从哪里开始。我添加了单例,但我不知道如何在我的中心文件中访问它。这是我想做的,但我愿意接受更好的方法:
MyHub.cs
using (PlayerContext dbContext = new PlayerContext(/* Singleton needs to go here */))
{
// do database stuff
}
我用 .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
}
}
使用 SignalR hub 上的依赖注入来注入 EF DbContext 是一个错误的选择,因为 SignalR hub 本身是一个 Singleton,不应该有较低生命周期的依赖,你最终会收到警告。这意味着,您不能将 DbContext 注册到 PerRequest/Transient 生命周期范围,只能使用单例。将 DbContext 注册为 Singleton 是一个非常糟糕的选择。创建新的上下文并不昂贵,但是您的具有单例上下文的集线器将在一段时间后呈指数增长。
我建议使用 Hub 的 DbContextFactory 类,在你的 hub 中从工厂请求新的 DbContext 并将其放入 using 语句。您还可以将工厂本身注册为单例,并使集线器构造函数中的依赖关系更加清晰。
using (var dbContextScope = dbContextScopeFactory.Create(options))
{
//do database stuff
dbContextScope.SaveChanges();
}
似乎仍然没有记录访问范围内的服务。但是查看源代码我们可以看到 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
}
这在 .net Core 3.1 中对我有用 Entity Framework Core 和 SignalR。我不必向启动添加任何内容(事实上,在 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();
}