3

我创建了一个项目来测试 NHibernate 3+ 与 Entity Framework 4.1,将其包装在存储库中,使其非常易于使用接口等进行测试。

我不想在存储库之外公开任何 ORM(我什至不公开 IQueryables)。一切都应该在该层中处理,直到我尝试以抽象方式处理获取,一切都很好。

Microsoft 添加预加载的实现在 Include 函数中使用魔术字符串 (yuck) 或 Linq 表达式 (yay)。它们的语法如下:

IQueryableThing.Include(o => o.Person);
IQueryableThing.Include(o => o.Company.Contact);
IQueryableThing.Include(o => o.Orders.Select(p => p.LineItem.Cost);

第一个只会加载关联的人。(parent) 第二个会加载关联公司和各个公司的联系方式。(父母和祖父母)。第三个将加载每个订单的所有关联订单、订单项和成本。

这是一个非常巧妙的实现。

NHibernate 使用稍微不同的方法。他们仍然使用 Linq 表达式,但是他们更多地使用了扩展方法(流利的方法)。

IQueryableThing.Fetch(o => o.Person);
IQueryableThing.Fetch(o => o.Company).ThenFetch(o => o.Contact);
IQueryableThing.FetchMany(o => o.Orders).ThenFetch(p => p.LineItem).ThenFetch(q => q.Cost);

(我不确定第三行是否是正确的语法)

我可以将表达式列表封装在一个单独的类中,然后将这些表达式应用于该类中的 IQueryable。所以我需要做的是标准化 Microsoft 表达式语法,然后通过遍历表达式树并重建每个表达式将其转换为 NHibernate 的语法。

这是真正棘手的部分。我必须保持特定的操作顺序才能为 IQueryable 调用正确的函数(必须以 Fetch 或 FetchMany 开头,每个后续都是“ThenFetch”或“ThenFetchMany”),这使我无法使用内置的-在 ExpressionVisitor 类中。

编辑:我最终创建了一个表达式解析器,它将对集合进行任何级别的属性、集合和选择嵌套,并生成一个表达式数组。不幸的是,内置的 Fetch 扩展方法不将 LambdaExpression 作为参数。

我目前坚持的部分是无法使用 nHibernate 的内置 Fetch 定义。看起来我可能不得不直接点击 Remotion 库的函数或注册我自己的扩展方法来满足他们的解析器。

时髦。

4

1 回答 1

0

你试过使用NHiberanteUtil.Initialize()吗?我没有尝试做你正在做的事情,但我认为 Initialize 将类似于Include().

于 2011-05-27T14:01:07.677 回答