nhibernate的定制<;设置>;质疑
我想对nhibernate的定制<;设置>;质疑,nhibernate,mapping,set,one-to-many,outer-join,Nhibernate,Mapping,Set,One To Many,Outer Join,我想对ClassA.ClassBCollection属性进行筛选和分页。我需要动态更改过滤 默认查询将产生如下结果: select * from ClassA left outer join ClassB on id == FK_ClassB 我可以定制nhibernate集合的查询吗 映射: <class name="ClassA"> <property name="Name" /> &l
ClassA.ClassBCollection
属性进行筛选和分页。我需要动态更改过滤
默认查询将产生如下结果:
select * from ClassA
left outer join ClassB
on id == FK_ClassB
我可以定制nhibernate集合的查询吗
映射:
<class name="ClassA">
<property name="Name" />
<set name="ClassBCollection">
<key column="FK_ClassB" on-delete="cascade" />
<one-to-many class="ClassB" />
</set>
</class>
<class name="ClassB">
<property name="Something"/>
</class>
如果我理解你的问题 我可以定制nhibernate集合的查询吗 …正确地说,答案是否定的 我的意思是,如果您考虑获取
ClassA
的实例,并对其
集合进行分页和过滤。那将永远在记忆中完成。(我在末尾附加了映射的功能)
我们可以改变方法
在这种情况下,当您需要一个过滤器并对集合项进行分页时,我强烈建议您换一种方式。创建标准(QueryOver
,HQL
)不是在ClassA
上,而是在ClassB
上
首先,我们必须扩展ClassB
映射:
<class name="ClassB">
<property name="Something" />
<many-to-one name="ClassA" column="FK_ClassB" fetch="join" />
</class>
因为我们使用了ClassAfetch=“join”
的映射,所以生成的SQL语句将非常类似于这个问题中的第一个片段
因此,通过这种方式,我们可以实现所需的SQL选择,但不能直接使用ClassA.ClassBCollection
。我们是这样做的
注:
我们可以影响
映射的过滤器/分页是where子句中的静态过滤器和获取值的样式
当作为ClassA
的属性加载ClassBCollection
时,Where子句将始终进行计算。它可能类似于where=“IsActive=true”
如果ClassA在ClassBCollection中有很多项目,我们可以管理如何借出它们。非常有效的方法是属性批量大小
我可以定制nhibernate集合的查询吗
我不完全确定这意味着什么。如果您的意思是,我可以在集合上查询并使用WHERE子句吗?答案是肯定的。以下是方法:
[TestFixture]
public class StackOverflowQuestion13496270Tests
{
public ISession session;
[SetUp]
public void SetUp()
{
session = // Get the current NHibernate session
}
[Test]
public void Query_ClassA()
{
var results = session.Query<ClassA>()
.Where( x => x.ClassBCollection.Any( y => y.Name == "Bob" ) )
.Fetch( x => x.ClassBCollection )
.Skip( 0 )
.Take( 50 )
.ToList();
}
[Test]
public void Query_ClassB()
{
var results = session.Query<ClassB>()
.Where( x => x.Name == "Bob" )
.Fetch( x => x.ClassAParent )
.Skip( 0 )
.Take( 50 )
.ToList();
}
public class ClassA
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<ClassB> ClassBCollection { get; set; }
}
public class ClassB
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
// Add this and the appropriate mapping modifications to be able to navigate back to the parent
public virtual ClassA ClassAParent { get; set; }
}
}
[TestFixture]
公共类StackOverflowQuestion13496270Tests
{
公开辩论会;
[设置]
公共作废设置()
{
session=//获取当前的NHibernate会话
}
[测试]
公共无效查询_ClassA()
{
var results=session.Query()
.Where(x=>x.ClassBCollection.Any(y=>y.Name==“Bob”))
.Fetch(x=>x.ClassBCollection)
.Skip(0)
.Take(50)
.ToList();
}
[测试]
公共无效查询_ClassB()
{
var results=session.Query()
.Where(x=>x.Name==“Bob”)
.Fetch(x=>x.ClassAParent)
.Skip(0)
.Take(50)
.ToList();
}
甲级公共课
{
公共虚拟整数Id{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟IList类集合{get;set;}
}
公共B类
{
公共虚拟整数Id{get;set;}
公共虚拟字符串名称{get;set;}
//添加此项和适当的映射修改,以便能够导航回父项
公共虚拟ClassA ClassAParent{get;set;}
}
}
这就像是一种折衷:使用ClassA.ClassBCollection或自定义查询,并与ClassA结果集合分离?明白了。我想我的处境和你一样。大集合,这不是延迟加载的最佳选择。所以,当我有ClassA时,我异步地去获取它集合的一部分。。。
[TestFixture]
public class StackOverflowQuestion13496270Tests
{
public ISession session;
[SetUp]
public void SetUp()
{
session = // Get the current NHibernate session
}
[Test]
public void Query_ClassA()
{
var results = session.Query<ClassA>()
.Where( x => x.ClassBCollection.Any( y => y.Name == "Bob" ) )
.Fetch( x => x.ClassBCollection )
.Skip( 0 )
.Take( 50 )
.ToList();
}
[Test]
public void Query_ClassB()
{
var results = session.Query<ClassB>()
.Where( x => x.Name == "Bob" )
.Fetch( x => x.ClassAParent )
.Skip( 0 )
.Take( 50 )
.ToList();
}
public class ClassA
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<ClassB> ClassBCollection { get; set; }
}
public class ClassB
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
// Add this and the appropriate mapping modifications to be able to navigate back to the parent
public virtual ClassA ClassAParent { get; set; }
}
}