NHibernate LINQ中动态组件关联实体的预加载正确语法
动态组件关联实体的NHibernate LINQ预加载语法问题
NHibernate支持通过dynamic-component配置动态组件,将动态/附加属性存储在POCO的IDictionary类型属性中,这些属性既可以是简单类型,也可以是一对多、多对一等关联实体。
已掌握的查询写法:
- 简单附加属性查询:
session.Query<Customer>().Where(c => c.DynamicProperties["DynProp"] == "XXX")
- 关联实体条件查询:
session.Query<Customer>().Where(c => ((AssocEntity)c.DynamicProperties["DynAssoc"]).Name == "XXX")
但尝试用Fetch(p => p.DynamicProperties["DynAssoc"])预加载动态组件中的关联实体时,会抛出异常:
ArgumentException: A fetch request must be a simple member access expression
要求:不通过修改NHibernate配置实现预加载,仅通过查询本身完成。
可行的实现方法
1. 使用QueryOver API(推荐)
QueryOver API对动态组件的关联预加载支持更灵活,通过JoinAlias结合Fetch.Eager可以实现预加载:
AssocEntity assocAlias = null; var customers = session.QueryOver<Customer>() .JoinAlias(c => c.DynamicProperties["DynAssoc"], () => assocAlias) .Fetch(() => assocAlias).Eager .Where(c => ((AssocEntity)c.DynamicProperties["DynAssoc"]).Name == "XXX") .List<Customer>();
2. LINQ表达式兼容写法(版本依赖)
部分新版本NHibernate的LINQ Provider支持解析带强制转换的Fetch表达式,可尝试:
var customers = session.Query<Customer>() .Where(c => ((AssocEntity)c.DynamicProperties["DynAssoc"]).Name == "XXX") .Fetch(c => (AssocEntity)c.DynamicProperties["DynAssoc"]) .ToList();
注意:该写法兼容性有限,若出现解析失败,优先使用QueryOver方案。
3. 查询级批量抓取(替代预加载)
若上述方法均不适用,可通过设置查询级批量抓取避免N+1查询,达到类似预加载的效果:
var customers = session.Query<Customer>() .Where(c => ((AssocEntity)c.DynamicProperties["DynAssoc"]).Name == "XXX") .SetBatchSize(10) .ToList();
内容的提问来源于stack exchange,提问作者user1211286
相关产品推荐
相关产品推荐

