使用ASP.NET,NHibernate / Fluent NHibernate的大多数无痛多租户实现

时间:2012-10-01 04:13:21

标签: asp.net-mvc nhibernate fluent-nhibernate multi-tenant

我试图在我使用的ASP.NET MVC应用程序中实现多租户,它使用NHibernate。虽然我可以控制数据库以实现多租户。我试图找出使用NHibernate过滤数据库查询的最佳方法。

我想知道是否有一种无痛的方式,我可以使用NHibernate向数据库的每个CRUD查询附加一个条件(类似WHERE InstanceID = 1)。

我查看了全局过滤器。但我不确定我是否以正确的方式使用它。我试过这样的事情。

NHibernateSession.GetDefaultSessionFactory().GetCurrentSession()
.EnableFilter("instance-filter").SetParameter("InstanceId", "2");

但它似乎没有用。 NHibernate全局过滤器的任何好例子/过滤所有具有条件的数据库查询的任何好方法都将受到高度赞赏。

1 个答案:

答案 0 :(得分:4)

我一直在寻找同样的事情,我的一个小项目仍处于规划阶段。我使用单个数据库的最完整实现是由Michael Valenty在他的博客文章Bolt-on Multi-Tenancy in ASP.NET MVC with Unity and NHibernate: Part II – Commingled Data中编写的。他还使用全局过滤器。

为了完整起见,以下是他使用的映射:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <filter-def name="tenant">
        <filter-param name="id" type="System.Int32" />
    </filter-def>
</hibernate-mapping>

对于每个实体:

<class name="User" table="[user]">
    <id name="Id" column="user_id">
        <generator class="identity" />
    </id>

    <property name="Username" />
    <property name="Email" />

    <filter name="tenant" condition="tenant_id = :id" />
</class>

之后,他使用他选择的IoC容器将参数值注入ISession的实例。

session.EnableFilter("tenant").SetParameter("id", c.Resolve<Tenant>().Id);

还有一个拦截器要实现 - 在保存实体(OnSave方法)时写入当前租户id的值,并在通过id加载实体时检查给定实体是否属于当前租户( OnLoad方法)。 OnLoad覆盖是必要的,因为在按ID加载实体时不会应用租户过滤器。