3
我需要在Get/Load方法上應用Nhibernate不支持的過濾器。什麼是在獲取/加載上應用過濾器的一些技術。 我知道一個我可以在DefaultLoadEventListener中修改值的地方。任何人都可以提出一些更好的技巧Nhibernate的Get和Load方法不支持會話過濾器嗎?
我需要在Get/Load方法上應用Nhibernate不支持的過濾器。什麼是在獲取/加載上應用過濾器的一些技術。 我知道一個我可以在DefaultLoadEventListener中修改值的地方。任何人都可以提出一些更好的技巧Nhibernate的Get和Load方法不支持會話過濾器嗎?
你可以使用攔截器來實現這一點。下面的代碼在嘗試獲取對象時應用過濾條件。
代碼的重要部分是,重寫OnPrepareStatement方法,它根據給定的條件將獲取SQL更改爲過濾器。基於文本的匹配是做這件事的非常粗略的方法,但我希望你明白。
public class TenantInterceptor : EmptyInterceptor
{
private ISession _session;
public override void SetSession(ISession session)
{
_session = session;
base.SetSession(session);
}
public override object GetEntity(string entityName, object id)
{
object entity = base.GetEntity(entityName, id);
if (entity != null && entity.GetType().IsAssignableFrom(typeof(User)))
{
var filter = _session.GetEnabledFilter("Tenant") as FilterImpl;
if (filter != null)
{
var filterValue = filter.Parameters["name"];
var user = entity as User;
if (!user.Tenant.Equals(filterValue))
return null;
}
}
return entity;
}
public override SqlString OnPrepareStatement(SqlString sql)
{
if (sql.ToString().EndsWith("FROM \"User\" user0_ WHERE user0_.Id=?"))
{
var filter = _session.GetEnabledFilter("Tenant") as FilterImpl;
if (filter != null)
{
var filterValue = filter.Parameters["name"];
sql = sql.Append(string.Format(" And user0_.Tenant = '{0}'",filterValue));
}
}
return base.OnPrepareStatement(sql);
}
}
但是,當我們在一個實體內部收集時,這個過濾器沒有被應用。例如,我有角色的活動過濾器。我有一個用戶實體,裏面有一個角色集合。如果某個角色變得不活躍,那麼當我獲取/加載用戶時,所有角色都來自db,包括不活動的角色。 – TBAG 2015-02-16 09:50:36
即使這樣的情況下,我認爲仍然preprerestatment被解僱,你可以修補SQL只加載你想要的。 – 2015-02-16 12:39:02