NHibernate可液化性

NHibernate可液化性,nhibernate,iqueryable,Nhibernate,Iqueryable,我有一些代码: 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; } } 公共级河马 { 公共

我有一些代码:

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; } 
}
公共级河马
{
公共虚拟整数Id{get;set;}
公共虚拟字符串名称{get;set;}
}
公立动物园
{
公共虚拟整数Id{get;set;}
公共虚拟IQueryable Hippos{get;set;}
}
我可以在NHibernate(或流利的NHibernate)中创建这样的河马吗? 或者我可以将会话传递给此对象吗

我怎么能做到?(在NHibernage.Linq或NHibernate.CollectionQuery的帮助下?)

我的目标是这样的:

_session.Query<Zoo>().Where(e => e.Hippos.Where(h=>h.Name=="Bobby").Any())
\u session.Query().Where(e=>e.Hippos.Where(h=>h.Name==“Bobby”).Any())

当您通过
会话.Query定义查询时,
看起来该集合已被访问,但未被访问。它只是在转换为sql的结果表达式中引用。因此,查询页面会将限制转发到数据库,因此只获取少量记录。例如,以下查询只返回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>();
更新:

可查询属性的实验代码。不漂亮但有用

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();
classzoomap:ClassMap
{
公共ZooMap()
{
...
地图(x=>x.河马)
.CustomType()
.公式(“1”)
.ReadOnly();
}
}
类QueryableHipposUserType:ICompositeUserType
{
公共对象组装(对象缓存、ISessionImplementor会话、对象所有者)
{
返回缓存;
}
公共对象深度复制(对象值)
{
返回值;
}
公共对象反汇编(对象值,ISessionImplementor会话)
{
返回值;
}
公共布尔等于(对象x、对象y)
{
返回true;
}
公共int GetHashCode(对象x)
{
返回0;
}
公共对象GetPropertyValue(对象组件,int属性)
{
返回null;
}
公共布尔可换
{
获取{return false;;}
}
公共对象NullSafeGet(IDataReader dr、字符串[]名称、ISessionImplementor会话、对象所有者)
{
var zooId=((动物园)所有者).Id;
return((NHibernate.ISession)session).Query().Where(hippo=>hippo.ContainingZoo.Id==zooId);
}
public void NullSafeSet(IDbCommand cmd,对象值,int索引,bool[]可设置,ISessionImplementor会话)
{
}
公共字符串[]属性名称
{
获取{返回新字符串[0];}
}
公共IType[]属性类型
{
获取{return new IType[]{NHibernateUtil.Int32};}
}
公共对象替换(对象原始、对象目标、ISessionImplementor会话、对象所有者)
{
归还原件;
}
公共类型ReturnedClass
{
获取{return typeof(IQueryable);}
}
public void SetPropertyValue(对象组件、int属性、对象值)
{
}
}
var someZoo=session.Get(zooId);
var theHappyHippos=someZoo.Hippos.Where(h=>h.Name==“Bobby”).ToList();

对于发布的查询,没有什么特别需要的,只是
IList Hippos{get;protected set;}
我知道IList,但是默认情况下,当我调用此属性时,它会返回数据库中的所有Hippos,但我需要查询。我的动物园有100500只河马,我想使用ZooForm中的页面,然后你会有
\u session.Query()。选择many(e=>e.hippos)。Where(h=>h.Name==“Bobby”)。Skip(pageindex*pagesize)。Take(pagesize)。OrderBy(h=>h.Id)。ToList()
用于每个页面,因此不需要IQueryableyes,但对于每个小页面,SQL将返回所有记录,即使我需要一个页面。在每个来自用户的http请求中,一个页面(50)的所有记录(100500)…我了解id。我知道如何工作\u session.Query()。在我的问题中,我要问的是,我如何使这个“t”看起来像是访问了集合,但它不是。它只是在转换为sql的结果表达式中被引用。带有导航属性。我知道,默认情况下,NHibernate从DB获取所有记录(进入导航属性)对不起,我的英语不好,也许你不明白我的问题?会话管理会很难使用一个简单的属性,所以我能想到的最好方法是:
public IQueryable Hippos(ISession session){return session.Query()。在哪里(h=>h.ContainingZoo.Id==this.Id);}
。请注意,会话保留连接、事务和缓存,因此使用另一个会话可能会把事情搞砸。在MVC模式(在我的应用程序中)中,模型现在不涉及会话(或实体框架中的上下文),只涉及IQueryable属性:(因此,我无法从客户端(模型)传递会话,只能从会话中收集IQueryable…我强烈反对这样做,但您可以实现
ICompositeUserType
来设置对象脱水时的IQueryable。会话关闭时会导致过时的IQueryable。如果需要,我可以发布一些代码。)
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();