0

我正在尝试将一些复杂的查询模式包装到扩展方法中,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* 的东西,我想我更喜欢它而不是传递会话。但我还没有找到访问它的方法(会话属性NhQueryProvider受保护)。我是否错过了其他一些方法来摆脱这种表达?

4

2 回答 2

2

你必须使用反射:

IQueryable<Product> query = Session.Query<Product>();
ISession session = query.Provider.GetType().GetProperty("Session", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(query.Provider, null) as ISession;
于 2013-06-07T18:16:57.563 回答
0

我相信您可能会从使用QueryObject 模式中受益——
您将定义一个方法,该方法接受一个ISession参数并在其上调用查询;
您可以使用查询对象的属性来定义不同的搜索词,而不是求助于字符串数组解决方案。

Ayende有一点凉爽的味道

于 2012-08-27T19:58:41.980 回答