代码之家  ›  专栏  ›  技术社区  ›  Kristoffer

NHibernate实体松耦合

  •  1
  • Kristoffer  · 技术社区  · 16 年前

    假设我有一个名为MyItem的实体。它可以包含在许多“父母”中,比如某个集合和其他集合。因为它可以包含在许多父项中,并且由于我不想让MyItem知道父项,所以我希望MyItem中没有任何引用父项的属性。

    因为一个父对象,像SomeCollection一样,可以包含许多myitem,所以我觉得需要某种分页来从父对象获取子对象。这将阻止我在某个集合中拥有引用MyItems的属性。不管你是否懒散,它总是“要么全有要么全无”(对吧?).

    我确实需要 一些 但在MyItem实体及其父实体之间的引用,以数据库中的映射表的形式。

    问题:

    • 如何为此创建映射? 我可以有地图吗,或者 保持业务关系 而是逻辑?
    • 我该如何查询 哪些MyTION实体存在于 什么收藏品?我能用ICriteria只访问一次数据库吗?
    2 回复  |  直到 16 年前
        1
  •  1
  •   Lachlan Roche    16 年前

    Many-to-One
    父级包含一个属性子级,子级可以从多个父级链接。

    class Parent
    {
        public virtual MyItem Child { get; set; }
    }
    
    <class name="Parent">
        <many-to-one name="Child" column="MyItemId" />
    </class>
    

    Many-to-Many with a join table
    父级包含子级的集合,子级可以从多个父级链接。

    class Parent
    {
        public virtual IList<MyItem> Children { get; set; }
    }
    
    <class name="Parent">
        <bag name="Children" table="parent_myitem">
            <key column="parentid" />
            <many-to-many class="MyItem" column="MyItemId" />
        <bag>
    </class>
    

    Criteria Querying

    // find Parent with child named "foo".
    DetachedCriteria.For<Parent>()
        .CreateAlias("Child", "c")
        .Add(Restrictions.Eq("c.Name", "foo"));
    
    // find Parent with particular child
    DetachedCriteria.For<Parent>()
        .Add(Restrictions.Eq("Child", child ));
    
    
    // find Parent with one of children named "foo".
    DetachedCriteria.For<Parent>()
        .CreateAlias("Children", "c")
        .Add(Restrictions.Eq("c.Name", "foo"));
    
    // find a "page" of children for a parent
    DetachedCriteria.For<Parent>()
        .Add(Restrictions.Eq("Id", parent.Id ))
        .CreateAlias("Children", "c")
        .SetFirstResult( 1041 )
        .SetMaxResults( 20 )
        .GetExecutableCriteria( session )
        .List<MyItem>();
    

    通过在第一次访问中仅延迟加载整个子集合,然后在后续的“页面”上索引它,最后的查询可能会或可能不会更有效地完成。这取决于你的数据和使用情况。

    除非我事先知道子集合将是巨大的,否则我将首先采用延迟加载路径。如果计时和 profiling 显示严重的缓慢,然后我会切换到标准方法。

        2
  •  0
  •   Jaya Wijaya    16 年前

    我有一个和你一样的案子。我有一个配置类,可以是全局配置、项目特定配置或用户特定配置。我所做的是:

    1. 我像往常一样将父对象映射到所有可能的父对象(全局除外,它表示应用于所有父对象,所以没有父对象)
    < class name="ConfigurationDomain" table="configuration">  
        < property name="ProjectId" column="project_id" type="int" insert="false" update="false" />  
        < property name="UserId" column="user_id" type="int" insert="false" update="false" />  
        < many-to-one name="Project" column="project_id" lazy="false" />  
        < many-to-one name="User" column="estimator_id" lazy="false" />
    < /class>  
    
    1. 我将配置映射为每个可能的父级中的集合
    < class name="UserDomain" table="user">  
        < set name="ConfigurationList" lazy="true" cascade="all-delete-orphan">  
          < key column="user_id" />  
          < one-to-many class="ConfigurationDomain" />  
        < /set>  
    < /class>  
    
    < class name="ProjectDomain" table="user">  
        < set name="ConfigurationList" lazy="true" cascade="all-delete-orphan">  
          < key column="project_id" />  
          < one-to-many class="ConfigurationDomain" />  
        < /set>  
    < /class>
    

    就这样对我有效。如何访问id为55的用户的配置如下:

    我不使用someUser.ConfigurationList,因为它很慢。我只映射父对象,以便在HQL中执行此操作(速度更快):

    select c from ConfigurationDomain c where c.UserId=55
    

    为了获得全局配置,我将执行以下操作:

    select c from ConfigurationDomain c where (c.UserId IS NULL) and (c.ProjectId IS NULL)
    

    经过反思,我认为如果您决定使用HQL,甚至可以删除集合映射。

    注意:我在NHibernate的早期使用过标准,但后来我发现HQL对我来说更强大一些,其他人对此可能有不同的看法。

    推荐文章