在NHibernate+中重新编写Linq表达式;DDD上下文

在NHibernate+中重新编写Linq表达式;DDD上下文,nhibernate,linq-expressions,Nhibernate,Linq Expressions,关于转换Linq表达式,我有一个棘手的问题。我仔细搜索了一下,但似乎找不到任何关于这个案子的东西。我对Linq相当熟悉,至少在创建lambda并将其传递给方法方面是这样,但在表达式方面我有点弱 首先,一些上下文:我有一个基于NHibernate的通用持久性解决方案,在许多DDD ish项目中使用。对于一个集合中的给定子集合本质上可能是无限的(即非常大的)特殊情况,我不能简单地映射集合或包,因为将整个集合加载到内存中是不可接受的。在这种体系结构中,使用API的代码不可能直接与存储库对话以执行查询或

关于转换Linq表达式,我有一个棘手的问题。我仔细搜索了一下,但似乎找不到任何关于这个案子的东西。我对Linq相当熟悉,至少在创建lambda并将其传递给方法方面是这样,但在表达式方面我有点弱

首先,一些上下文:我有一个基于NHibernate的通用持久性解决方案,在许多DDD ish项目中使用。对于一个集合中的给定子集合本质上可能是无限的(即非常大的)特殊情况,我不能简单地映射集合或包,因为将整个集合加载到内存中是不可接受的。在这种体系结构中,使用API的代码不可能直接与存储库对话以执行查询或以这种方式限制结果。我当然不可能在API中有一个集合,而是公开方法来检索子对象的相关子集(如果这不起作用,我会这么做),但我正在尝试做一些稍微不同的事情,我几乎已经成功了

这些项目是用Fluent映射的(不是自动映射),所以我在表单中向我的基本映射类添加了一个方法

HasManyQueryable<TCollection>(Expression<Func<T, IQueryable<TCollection>>> memberExpression, Expression<Func<T, TCollection, bool>> selector)
这指定了所有
事务
子集之间的映射,其中
Transaction.User
是提供的
User
u,而
User.Transactions
属性是
IQueryable
。当构建一个实际的
用户
对象时,我需要将其转换为

Expression<Func<Transaction, bool>> expression = (t => t.User == this)
这只能在选择器为
Func
时工作,因此我的最终需要是将原始表达式转换为
Func
,从而生成
Func

这给了我一个
IQueryable
集合,其中所有的查询操作都作为Linq到NHibernate查询来执行,因此整个集合永远不会加载到内存中(是的,我知道您可以构建一个查询,使它真正做到这一点,但我可以在代码检查时捕获这些查询)

呸。希望这是有道理的


任何有leet Expression re-write技能的人都能为我指出正确的方向吗?

老实说,从领域的角度来看,我对你试图做的事情有些茫然。但从代码的角度来看,听起来您只需要一个curried函数——一个接受用户并生成Func的方法。一个示例方法是这样的,尽管您可以内联执行相同的操作:

Func<Transaction,bool> UserSpecificSelector(User user,
                                            Func<User,Transaction,bool> selector)
{
    return t => selector(user, t);
}
Func UserSpecificSelector(用户,
Func选择器)
{
返回t=>选择器(用户,t);
}
因此,要获得特定于用户的选择器,您需要

Func<User, Transaction, bool> selector = // whatever;
User user = //whatever;
Repository.For<Transaction>().Where(t => selector(user, t));
Func选择器=//随便什么;
User=//随便什么;
Repository.For(),其中(t=>selector(user,t));

我怀疑您是否需要直接使用
表达式
层次结构,除非您正在实现自己的查询提供程序,而在本例中,您并不是这样做的。

是的,我很确定您是正确的。我发现另一个答案建议用咖喱来做一些不同的事情,然后突然说“bing!”。现在重新编写代码,看看它是否会运行。从域的角度来看,我试图实现的是使NHibernate集合成为NH Linq提供程序的一个门面。这是相当抽象的,我同意我没有特别好地描述它……那么恭喜你,你是我听说的第一个咖喱被称为“叮”的人我肯定花了一段时间来摸索,而不是“搞什么鬼?”。直到3.5时代的lambdas,我才真正在.NET中获得代表。花了一段时间才理解,但现在这是第二天性。所以在这种情况下,我认为它是一个委托返回一个委托,这很有意义。可悲的是,我试图做的领域的事情被证明是不切实际的,但我现在在阿森纳有了一个新的技巧。谢谢对于那些关心的人。。。结果证明我想做的事做不到。不是表达式/Func位-如接受的答案所示,可以通过咖喱来解决。你就是不能按照我想要的方式从NHibernate中得到正确的Linq查询。我最终选择了一个不那么整洁但有效的解决方案。
Func<Transaction,bool> UserSpecificSelector(User user,
                                            Func<User,Transaction,bool> selector)
{
    return t => selector(user, t);
}
Func<User, Transaction, bool> selector = // whatever;
User user = //whatever;
Repository.For<Transaction>().Where(t => selector(user, t));