获取Entity Framework 4.1和NHibernate的策略封装

时间:2011-05-26 15:23:49

标签: entity-framework-4.1 expression-trees linq-to-nhibernate encapsulation fetching-strategy

我创建了一个项目来测试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);

第一个只会加载相关人员。 (父) 第二个将加载关联公司和每个公司的联系人。 (父母和祖父母)。 第三个将加载每个订单的所有相关订单,订单项和费用。

这是一个非常漂亮的实现。

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库的函数或者注册我自己的扩展方法来满足它们的解析器。

时髦。

1 个答案:

答案 0 :(得分:0)

您是否尝试过使用NHiberanteUtil.Initialize()?我没有尝试过你正在做的事情,但我认为Initialize的工作方式类似于Include()