首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate筛选器集合

NHibernate筛选器集合
EN

Stack Overflow用户
提问于 2009-09-17 00:32:42
回答 2查看 6K关注 0票数 5

使用NHibernate,我想过滤类中的一个集合,使其只包含可能对象的一个子集。下面我将包括一个示例表数据来帮助解释。我找不到使用NHibernate做到这一点的方法。

表:DataObject

DataObjectId(主键)/ Name / CurrentVersion

代码语言:javascript
复制
11          "data.txt"      2
12          "info.txt"      3

表:DataObjectVersion

Id / Comment / VersionNumber / DataObjectId(FK)

代码语言:javascript
复制
31   "Genesis"         1          11     <= Ignore this object
32   "Changed data"    2          11     <= Get this object
34   "Genesis"         1          12     <= Ignore this object   
35   "Changed info"    2          12     <= Ignore this object
36   "Added info"      3          12     <= Get this object

我想在一个命令中为每个DataObject连接一个非外键DataObject.CurrentVersion = DataObjectVersion.VersionNumber。

下面是类和映射文件:

代码语言:javascript
复制
public class DataObject
{
  public virtual int DataObjectId { get; set; }
  public virtual string Name { get; set; }
  public virtual int CurrentVersionNumber { get; set; }
  public virtual IList<DataObjectVersion> Versions { get; set; }
}

<class name="DataObject" table="DataObject" lazy="false">
    <id name="DataObjectId" column="DataObjectId" type="int">
      <generator class="assigned" />
    </id>
    <property name="Name" column="Name" type="String(512)" />
    <property name="CurrentVersionNumber" column="CurrentVersionNumber" type="int" />
    <bag name="Versions" cascade="all-delete-orphan" inverse="true" lazy="false" >
        <key column="DataObjectId" />
        <one-to-many class="DataObjectVersion" />
    </bag>
</class>

public class DataObjectVersion
{
    public virtual int DataObjectVersionId { get; set; }
    public virtual string Comment { get; set; }
    public virtual int VersionNumber { get; set; }
    public virtual int DataObjectId { get; set; }
}

<class name="DataObjectVersion" table="DataObjectVersion" lazy="false">
    <id name="Id" column="DataObjectVersionId" type="int">
      <generator class="assigned" />
    </id>
    <property name="Comment" column="Comment" type="String(512)" />
    <property name="VersionNumber" column="VersionNumber" type="int" />
    <property name="DataObjectId" column="DataObjectId" type="int" />
</class>  
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-09-18 10:26:21

如果要按需筛选集合,则使用筛选器是一个有效的选择。您需要在Version类和bag元素中声明滤镜,并应用NHibernateSession.EnableFilter方法中的滤镜

如果你总是想获取包中的一个版本,那么在包的映射中实现一个'where‘:

代码语言:javascript
复制
<bag name="Versions" cascade="all-delete-orphan" inverse="true" lazy="false" where="CurrentVersionNumber = Versions.VersionNumber" >
    <key column="DataObjectId" />
    <one-to-many class="DataObjectVersion" />
</bag>

请注意,在“where”中,您编写的是正确的SQL,而不是HQL,因此,我上面编写的正确的SQL可能必须更改以反映您的模式

此外,如果要获取单个对象,设置一个袋子和相应的IList可能是一种过度的杀伤力。在类中应用公式属性和DataObjectVersion对象可能更合适

在DataObject类中,将IList替换为

代码语言:javascript
复制
public virtual DataObjectVersion Version { get; set; }

并在映射中将'bag‘替换为行中的内容

代码语言:javascript
复制
<property name="Version" type="DataObjectVersion" update="false" insert="false" formula="(select v.DataObjectVersionId, v.Comments, v.VersionNumber, v.DataObjectId from DataObjectVersion v where v.VersionNumber  = CurrentVersionNumber)" />

同样,只允许正确的SQL

我将计算属性与原生数据类型(datetime、string等)一起使用,获取实体可能(也可能不)需要更多或不同的内容

最后但并非最不重要的一点是,您可以在获取主要对象DataObject之后,通过在集合上创建过滤器来对该集合应用过滤器

代码语言:javascript
复制
IList<DataObjectVersion>  fVersion = 
    NHibernateSession.CreateFilter(do.Versions, "where VersionNumber = :ver")
        .SetParameter("ver", do.CurrentVersionNumber)
        .List<DataObjectVersion>();

在未初始化do.Versions集合的情况下,仅在单独的fVersion集合中获取结果,并且这是在已经往返于数据库以进行DataObject获取之后的第二次选择。

票数 11
EN

Stack Overflow用户

发布于 2009-09-17 01:12:32

假设您的VersionNumber随着用户更改数据而递增,而您试图获取最新的数据。如果您将VersionNumber视为“年龄”字段(即,其中0是最新/最年轻的版本,1是下一个最旧的版本,依此类推),那么您的问题就变成了如何获取年龄为0的所有实体。这可以使用一个过滤器来完成:http://nhibernate.info/doc/nh/en/index.html#objectstate-filters

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1436172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档