使用单个数据库多模式的ASP.NET MVC多租户应用程序:从应用程序调用存储过程尝试访问dbo表

时间:2014-02-06 08:18:03

标签: sql sql-server multi-tenant

我正在使用ASP.NET MVC,SQL Server,Dapper开发一个多租户应用程序,其中包含单个数据库和每个租户的多个模式。 将为租户分配拥有租户架构的db用户。我在dbo中有一组表,而所有模式都有另一组表。

说我有dbo.TenantanySchema.Table1。从我为anyschema用户设置连接字符串的应用程序,如果我调用select * from Table1,它将返回anySchema.Table1的值。如果我在商店过程中有相同的查询,则在尝试访问dbo.Table1时会抛出错误。

我为租户数据库用户提供了对dbo的执行访问权限,因为所有租户都在dbo.SP_Name

共享单个SP

如何执行以租户db用户身份登录的存储过程,访问anyschema的Table1,以便所有租户都可以使用单个SP。

1 个答案:

答案 0 :(得分:2)

假设我们的数据库tenant1tenant2中有两个用户拥有自己的架构(也称为tenant1tenant2)。

我们为每个租户创建了一个Contacts表格,因此我们有tenant1.Contactstenant2.Contacts

在我们的应用程序中,我们使用Dapper执行以下SQL。我们使用租户特定的连接字符串,该字符串使用租户的SQL Server登录详细信息。

select * from Contacts

由于我们没有在SQL中指定架构,因此从执行SQL的用户的默认架构推断。因此,对于tenant1,它会查询tenant1.Contacts,而对于tenant2,它会查询tenant2.Contacts

现在我们将在dbo架构中创建一个执行相同查询的存储过程:

CREATE PROCEDURE GetContacts
AS
BEGIN
    select * from Contacts
END
GO

请注意,我在存储过程的SQL中指定了架构。

当我们从应用程序执行存储过程时,仍然可以从当前用户推断出存储过程的模式,但是SP中的SQL推断出来自SP的模式。 即可。因此,如果SP属于dbo模式,它将对dbo.Contacts表执行查询。

这就是你的情况。您已在dbo模式中创建了一个存储过程,并期望它根据租户的默认模式执行SQL。

您有几个选择

  1. 将架构作为参数传递给存储过程,并使用动态SQL - How to pass schema as parameter to a stored procedure in sql server?
  2. 为每个租户创建一个SP版本,例如tenant1.SP_Nametenant2.SP_Name
  3. 不要使用存储过程。