我正在尝试将一些复杂的查询模式包含在IQueryable<Foo>
的扩展方法中,并偶尔需要在其中进行一些外连接。
static IQueryable<Foo> Filter(this IQueryable<Foo> foos, params string[] searchTerms)
{
//...
return from t in session.Query<Tags>()
from f in foos
where
(t.Name.Contains (searchTerms[0] && f.Tags.Contains(t))
|| f.Name.Contains(searchTerms[0]
select f;
}
另一种情况还要求会话访问进行一些保存操作(是的,是的,副作用很糟糕。它用于跟踪查询模式)。
我在第一种情况下通过将标签集合作为参数传递来解决这个问题,虽然对于调用者来说有点难看,但工作正常,但显然不能扩展,而且唯一的其他选择我为了解决这个问题,我已经能够通过直接传递ISession
来实现这一点。
我希望有一些帮助方法,如下所示,我可以通过扩展方法调用:
static ISession GetSession<T> (IQueryable<T> query)
{
// do magic
}
即使它涉及向下转发可查询,或查询提供程序或其他东西到Nh *我想我更喜欢它传递会话。但我还没有找到一种方法来访问它({{上的会话属性) 1}}受保护)。我是否错过了其他一些方法来解决这个问题呢?
答案 0 :(得分:2)
你必须使用反射:
IQueryable<Product> query = Session.Query<Product>();
ISession session = query.Provider.GetType().GetProperty("Session", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(query.Provider, null) as ISession;
答案 1 :(得分:0)
我相信您可能会因使用QueryObject pattern而受益
您将定义一个采用ISession
参数并在其上调用查询的方法;
您可以使用查询对象的属性定义不同的搜索项,而不是求助于字符串数组解决方案。
Ayende有点cooler flavour