选择具有多个子实体的实体

时间:2011-05-13 20:36:44

标签: nhibernate activerecord castle-activerecord

使用Active Record / NHibernate,我试图选择一个有多个子集合的实体(Site)。

只有一个站点具有给定的siteId,但FindAll返回站点28次;由于它正在加载的子集合,它正在被复制。如何让它只加载1个站点和子集合的数组?我不介意它是5个选择,一个是抓住网站,然后是每个子集合1个。

以下是代码:

var criteria = DetachedCriteria.For<Site>()
                    .CreateAlias("TimeZone", "tz", NHibernate.SqlCommand.JoinType.InnerJoin)
                    .CreateAlias("Logos", "l", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
                    .CreateAlias("SiteColors", "sc", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
                    .CreateAlias("ManagerUsers", "mu", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
                    .Add(Restrictions.Eq("Id", siteId));
                var sites = FindAll(criteria);

我应该提一下,我也尝试过使用fetch的hql方法,但是fetch不是取来的!它只返回一个站点(好),但没有一个子集合被急切地加载(坏)。

public static Site Get(int id)
        {
            var query = new SimpleQuery<Site>(@"
                from Site s
                where s.Id = ?
                inner join fetch s.TimeZone tc
                left join fetch s.Logos l
                left join fetch s.SiteColors sc
                left join fetch s.ManagerUsers mu
            ", id);
            var results = query.Execute().ToList();
            return results.FirstOrDefault();
        }

以下代码似乎有效,使用“未来”方法:

public static Site Get(int id)
        { 
            var session = ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(Site));
            var query = session.CreateQuery("from Site s left join fetch s.Logos where s.Id = :id").SetParameter("id", id).Future<Site>();
            session.CreateQuery("from Site s left join fetch s.SiteColors where s.Id = :id2").SetParameter("id2", id).Future<Site>();
            session.CreateQuery("from Site s left join fetch s.ManagerUsers where s.Id = :id3").SetParameter("id3", id).Future<Site>();
            return query.FirstOrDefault();
        }

我的所有数据模型类都继承自SimpleModel类,我将Equals和GetHashCode方法添加到:

public abstract class SimpleModel
    {
        protected SimpleModel()
        {
            DateCreated = DateTimeAccess.Now;
        }

        [PrimaryKey]
        [DocumentId]
        public virtual int Id { get; set; }

        [Property]
        public virtual DateTime DateCreated { get; set; }

        public override bool Equals(object obj)
        {
            if (obj is SimpleModel)
            {
                return Id.Equals(((SimpleModel)obj).Id);
            }
            else
            {
                return false;
            }
        }

        public override int GetHashCode()
        {
            return Id.GetHashCode();
        }
    }

1 个答案:

答案 0 :(得分:1)

根据您的条件致电SetResultTransformer(DistinctRootEntity)。它会将这些重复的Site实例折叠为单个实例。

有关详细信息,请参阅此主题:http://groups.google.com/group/nhusers/browse_thread/thread/9919812230702ccc