我正在关注本教程,以便通过 Entity Framework 6 CodeFirst 在 SQL Server 中使用行级安全性。教程代码示例展示了如何使用 IDbConnectionInterceptor 并在session_context
. HttpContext.Current.User.Identity.GetUserId()
要检索用户 ID,它使用与 Asp.Net 身份和 System.Web 命名空间相结合的静态访问器方法。
在我的多租户 Web 应用程序中,我希望将tenantId注入到DbConnectionInterceptor
使用 Unity 中(不创建与 的硬耦合HttpContext
)并在session_context
. 我发现DbConnectionInterceptor
需要在全局范围内注册(例如在应用程序启动时),因此您不能让 UnityDbConnectionInterceptor
为每个请求创建实例。
我的解决方案中还有 2 个 DbContext,代表 2 个不同的数据库(租户数据库和系统数据库),我只想应用session_context
到租户数据库。
看来我剩下的唯一选择是DbContext
通过 Unity将tenantId 注入到DbContext
实例中Opened()
,并在DbConnectionInterceptor
. 为此,我想到了interceptionContext
在方法中使用参数Opened()
。interceptionContext
有一个DbContexts
(复数)属性。没有这方面的文档,所以我认为这样的事情会起作用:
public void Opened(DbConnection connection, DbConnectionInterceptionContext interceptionContext)
{
var firstDbContext = interceptionContext.DbContexts.FirstOrDefault(d => d is TenantDataContext);
if (firstDbContext != null)
{
var dataContext = firstDbContext as TenantDataContext;
var tenantId = dataContext.TenantId;
DbCommand cmd = connection.CreateCommand();
cmd.CommandText = $"EXEC sp_set_session_context @key=N'TenantId', @value={tenantId};";
cmd.ExecuteNonQuery();
}
}
我的代码检查 DbContexts 集合是否包含TenantDataContext
作为第一个元素并执行sp_set_session_context
. 但我担心的是两个 DbContext 是否有机会同时存在?如果是这种情况,与我的其他数据库的连接也会设置session_context
我不需要的。我想知道为什么 Microsoft 将其作为集合属性而不是单个DbContext
属性提供。这个属性让你想知道多个 DbContext 是否可以使用同一个连接。
有没有人实现了我想要的?关于这个 interceptionContext 的任何解释对我也有帮助。