NHibernate IQueryable 属性
NHibernate IQueryable properties
我有一些代码:
public class Hippo
{
public virtual int Id { get; set; }
public virtual string Name {get;set;}
}
public class Zoo
{
public virtual int Id { get; set; }
public virtual IQueryable<Hippo> Hippos { get; set; }
}
我可以在 NHibernate(或 fluent nhibernate)中像这样创建 Hippos 吗?
或者我可以将 Session 传递给这个对象吗?
我该怎么做? (在 NHibernage.Linq 或 NHibernate.CollectionQuery 的帮助下?)
我的目标是这样的:
_session.Query<Zoo>().Where(e => e.Hippos.Where(h=>h.Name=="Bobby").Any())
当您通过 session.Query<>
定义查询时,看起来好像访问了集合,但实际上并没有。它只是在转换为 sql 的结果表达式中引用。因此查询页面会将限制转发给数据库,因此只会获取少数记录。例如下面的查询只会 return 50 只河马:
const int pagesize = 50;
_session.Query<Zoo>()
.SelectMany(e => e.Hippos)
.Where(h => h.Name=="Bobby")
.Skip(pageindex * pagesize).Take(pagesize)
.OrderBy(h => h.Id)
.ToList<Hippo>();
查询集合时不要与 someZoo.Hippos.Where(h=>h.Name=="Bobby").ToList()
混淆。这将触发延迟加载并获取动物园的所有河马。因此,DomainModel 上的集合可能包含大量项目并不是一个好主意。有人会在代码中使用它,在用小数据集开发时它不会崩溃。如果可能,最好只使用反向引用 somehippo.ContainingZoo
和查询
const int pagesize = 50;
_session.Query<Hippo>()
.Where(h => h.Name=="Bobby")
.Skip(pageindex * pagesize).Take(pagesize)
.OrderBy(h => h.Id)
.ToList<Hippo>();
更新:
可查询属性的实验代码。不漂亮但好用
class ZooMap : ClassMap<Zoo>
{
public ZooMap()
{
...
Map(x => x.Hippos)
.CustomType<QueryableHipposUserType>()
.Formula("1")
.ReadOnly();
}
}
class QueryableHipposUserType : ICompositeUserType
{
public object Assemble(object cached, ISessionImplementor session, object owner)
{
return cached;
}
public object DeepCopy(object value)
{
return value;
}
public object Disassemble(object value, ISessionImplementor session)
{
return value;
}
public bool Equals(object x, object y)
{
return true;
}
public int GetHashCode(object x)
{
return 0;
}
public object GetPropertyValue(object component, int property)
{
return null;
}
public bool IsMutable
{
get { return false; ; }
}
public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner)
{
var zooId = ((Zoo)owner).Id;
return ((NHibernate.ISession)session).Query<Hippo>().Where(hippo => hippo.ContainingZoo.Id == zooId);
}
public void NullSafeSet(IDbCommand cmd, object value, int index, bool[] settable, ISessionImplementor session)
{
}
public string[] PropertyNames
{
get { return new string[0]; }
}
public IType[] PropertyTypes
{
get { return new IType[]{ NHibernateUtil.Int32 }; }
}
public object Replace(object original, object target, ISessionImplementor session, object owner)
{
return original;
}
public Type ReturnedClass
{
get { return typeof(IQueryable<Hippo>); }
}
public void SetPropertyValue(object component, int property, object value)
{
}
}
var someZoo = session.Get<Zoo>(zooId);
var theHappyHippos = someZoo.Hippos.Where(h => h.Name=="Bobby").ToList();
我有一些代码:
public class Hippo
{
public virtual int Id { get; set; }
public virtual string Name {get;set;}
}
public class Zoo
{
public virtual int Id { get; set; }
public virtual IQueryable<Hippo> Hippos { get; set; }
}
我可以在 NHibernate(或 fluent nhibernate)中像这样创建 Hippos 吗? 或者我可以将 Session 传递给这个对象吗?
我该怎么做? (在 NHibernage.Linq 或 NHibernate.CollectionQuery 的帮助下?)
我的目标是这样的:
_session.Query<Zoo>().Where(e => e.Hippos.Where(h=>h.Name=="Bobby").Any())
当您通过 session.Query<>
定义查询时,看起来好像访问了集合,但实际上并没有。它只是在转换为 sql 的结果表达式中引用。因此查询页面会将限制转发给数据库,因此只会获取少数记录。例如下面的查询只会 return 50 只河马:
const int pagesize = 50;
_session.Query<Zoo>()
.SelectMany(e => e.Hippos)
.Where(h => h.Name=="Bobby")
.Skip(pageindex * pagesize).Take(pagesize)
.OrderBy(h => h.Id)
.ToList<Hippo>();
查询集合时不要与 someZoo.Hippos.Where(h=>h.Name=="Bobby").ToList()
混淆。这将触发延迟加载并获取动物园的所有河马。因此,DomainModel 上的集合可能包含大量项目并不是一个好主意。有人会在代码中使用它,在用小数据集开发时它不会崩溃。如果可能,最好只使用反向引用 somehippo.ContainingZoo
和查询
const int pagesize = 50;
_session.Query<Hippo>()
.Where(h => h.Name=="Bobby")
.Skip(pageindex * pagesize).Take(pagesize)
.OrderBy(h => h.Id)
.ToList<Hippo>();
更新:
可查询属性的实验代码。不漂亮但好用
class ZooMap : ClassMap<Zoo>
{
public ZooMap()
{
...
Map(x => x.Hippos)
.CustomType<QueryableHipposUserType>()
.Formula("1")
.ReadOnly();
}
}
class QueryableHipposUserType : ICompositeUserType
{
public object Assemble(object cached, ISessionImplementor session, object owner)
{
return cached;
}
public object DeepCopy(object value)
{
return value;
}
public object Disassemble(object value, ISessionImplementor session)
{
return value;
}
public bool Equals(object x, object y)
{
return true;
}
public int GetHashCode(object x)
{
return 0;
}
public object GetPropertyValue(object component, int property)
{
return null;
}
public bool IsMutable
{
get { return false; ; }
}
public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner)
{
var zooId = ((Zoo)owner).Id;
return ((NHibernate.ISession)session).Query<Hippo>().Where(hippo => hippo.ContainingZoo.Id == zooId);
}
public void NullSafeSet(IDbCommand cmd, object value, int index, bool[] settable, ISessionImplementor session)
{
}
public string[] PropertyNames
{
get { return new string[0]; }
}
public IType[] PropertyTypes
{
get { return new IType[]{ NHibernateUtil.Int32 }; }
}
public object Replace(object original, object target, ISessionImplementor session, object owner)
{
return original;
}
public Type ReturnedClass
{
get { return typeof(IQueryable<Hippo>); }
}
public void SetPropertyValue(object component, int property, object value)
{
}
}
var someZoo = session.Get<Zoo>(zooId);
var theHappyHippos = someZoo.Hippos.Where(h => h.Name=="Bobby").ToList();