NHibernate - 使用租户特定的表前缀

发布于 2024-11-03 07:17:20 字数 445 浏览 4 评论 0原文

我们正在使用 NHibernate 开发一个多租户应用程序,其中所有租户共享相同的数据库。

我们考虑的一种选择是为我们的数据库对象使用租户特定的前缀(我相信 Orchard 采取的方法相同)。

这至少为我们提供了某种租户数据恢复模型,并且意味着我们不必在大多数查询中包含租户 ID 过滤器。

所以我的问题是——有人采用了这种策略吗?如果是这样,你是怎么做的?

具体来说,我们可以为所有租户使用相同的 SessionFactory 吗?我们可以使用 NHibernate 在运行时为“新”租户生成一组新表(这样做安全吗)。

谢谢 Ben

[更新]

这是一项值得进行的调查,但最终我们认为共享模式更适合我们的需求。每个租户的模式显然可以更好地分离租户数据,但使维护变得更加困难。由于我们的租户仅存储少量数据,因此拥有 10 个表 * 1K 个租户的想法有点令人反感。

We are developing a multi-tenant application using NHibernate where all tenants share the same database.

One option we considered was to use a tenant specific prefix for our database objects (I believe this the same approach taken by Orchard).

This would at least give us some kind of recovery model for tenant data and would mean we wouldn't have to include a tenantid filter on most of our queries.

So my question - has anyone employed this strategy? If so, how did you go about it.

Specifically, can we use the same SessionFactory for all tenants and can we use NHibernate to generate a new set of tables for a "new" tenant at runtime (is it safe to do so).

Thanks
Ben

[Update]

This was a worthwhile investigation but ultimately we decided that a shared schema was more suitable for our needs. Schema per tenant clearly offers better separation of tenant data but makes maintenance more difficult. Since our tenants are only storing small amounts of data, the thought of having 10 tables * 1K tenants is a little off-putting.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清君侧 2024-11-10 07:17:20

您可能需要考虑几个定制/扩展点。

我认为您无法在租户之间共享同一个会话工厂。我认为最简单的事情可能是根据与会话工厂关联的租户更新映射。

public class EntitytMap:ClassMap<Entity>
{
     public EntitytMap()
    {
        Table("TableName");
        Schema(Session.TenantName);
        Id(p => p.Id, "Id").GeneratedBy.Identity();

如果您想让每个租户都有自己的架构,那么这应该可行。如果您想保持架构相同但在表上有一个前缀,您可以更改为:

public class EntityMap:ClassMap<Entity>
{
     public EntityMap()
    {
        Table(Session.TenantPrefix + "TableName");
        Schema("SCHEMA");
        Id(p => p.Id, "Id").GeneratedBy.Identity();

您也可以尝试提供您自己的 ConnectionProvider。从 NHibernate.Connection.DriverConnectionProvider 派生一个类,并在 nhibernate 配置文件中引用您自己的副本,而不是:

 <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

use

<property name="connection.provider">My.Project.DAL.NHibernate.CustomConnectionProvider, My.Project.DAL</property>

当调用 GetConnection 提供程序时,您可以根据租户指定您自己的连接字符串。

There are a couple of points of customization / extension that you may want to consider.

I don't think that you will be able to share the same session factory across tenants. I think that the simplest thing to do may be to update the mappings based on the tenant associated with the session factory.

public class EntitytMap:ClassMap<Entity>
{
     public EntitytMap()
    {
        Table("TableName");
        Schema(Session.TenantName);
        Id(p => p.Id, "Id").GeneratedBy.Identity();

If you want to have each tenant in their own schema, this should work. If you want to keep the schema the same but have a prefix on the table, you could change to:

public class EntityMap:ClassMap<Entity>
{
     public EntityMap()
    {
        Table(Session.TenantPrefix + "TableName");
        Schema("SCHEMA");
        Id(p => p.Id, "Id").GeneratedBy.Identity();

You can also try providing your own ConnectionProvider. Derive a class from NHibernate.Connection.DriverConnectionProvider and reference your own copy in the nhibernate configuration file instead of:

 <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

use

<property name="connection.provider">My.Project.DAL.NHibernate.CustomConnectionProvider, My.Project.DAL</property>

When the GetConnection provider is called, you can specify your own connection string based on the tenent.

梦里梦着梦中梦 2024-11-10 07:17:20

我们可以使用 NHibernate 为“新”租户生成一组新表吗
在运行时(这样做安全吗)

我建议您不要向您的 Web 应用程序授予执行这些 DDL 任务所需的权限级别。我会为 Web 应用程序保留正常 DML 操作的最低级别权限,并让后台服务作为“配置服务”运行。它的作用是对新租户进行架构修改,并且它也是放置任何其他租户配置任务(例如创建新文件夹、配置 IIS 等)的好地方。所有这些任务也需要时间,并且最好不要在单个 Web 中完成要求。后台数据库可以更新配置表,用有关其进度的信息更新它,直到其完成并且 Web UI 进入下一步。

can we use NHibernate to generate a new set of tables for a "new" tenant
at runtime (is it safe to do so)

I'd suggest that you wouldn't want to grant your web application the level of permissions required to perform these DDL tasks. I'd leave the web app with the minimum level of permissions for normal DML operations and have a background service operating as a 'Provisioning Service'. Its role would be schema modifications for the new tenant, and it is also a good place to put any other tenant provisioning tasks such as creating new folders, configuring IIS etc. All these tasks take time too and are best not done in a single web request. The background database can update a provisioning table, updating it with information about its progress until its complete and the web ui moves to the next step.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文