我试图在我使用的ASP.NET MVC应用程序中实现多租户,它使用NHibernate。虽然我可以控制数据库以实现多租户。我试图找出使用NHibernate过滤数据库查询的最佳方法。
我想知道是否有一种无痛的方式,我可以使用NHibernate向数据库的每个CRUD查询附加一个条件(类似WHERE InstanceID = 1
)。
我查看了全局过滤器。但我不确定我是否以正确的方式使用它。我试过这样的事情。
NHibernateSession.GetDefaultSessionFactory().GetCurrentSession()
.EnableFilter("instance-filter").SetParameter("InstanceId", "2");
但它似乎没有用。 NHibernate全局过滤器的任何好例子/过滤所有具有条件的数据库查询的任何好方法都将受到高度赞赏。
答案 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加载实体时不会应用租户过滤器。