简体   繁体   中英

NHibernate Projections (QueryOver.SelectList) limits

I'm new on stackoverflow and i hope this question will be appreciated.

Simply said: I select everything from table x left outer join table y. Table x has way too many columns so i make new object x. This object is used for the Projection. I can project every single column of table xi want. But when i try to project/select an collection (the collection of table y) then i get the same error: 'Index was outside the bounds of the array'.

My question: Does NHibernate support to select/project a collection at all? Because i've seen this question multiple times by searching on google (and stackoverflow), but none of those questions were answered.

Code example:

public class X
{
    public virtual int ID { get; set; }
    public virtual int IDontNeedMoreInfoAboutClassXItTakesToMuchTimeToRetrieve { get; set; }
    public virtual IList<Y> YCollection { get; set; }
}

public class Y
{
    public virtual int YID { get; set; }
}

public class XRepository{
    public ISession Session {get; set;}
    public IList<X> Get()
    {

        X xAlias = null;
        Y yAlias = null;
        X resultAlias = null;
        return Session.QueryOver<X>()
            .JoinAlias(() => xAlias.YCollection, () => yAlias, JoinType.LeftOuterJoin)
            .SelectList(list => list
                .SelectGroup(() => xAlias.ID).WithAlias(() => resultAlias.ID)
                .SelectGroup(() => xAlias.YCollection).WithAlias(() => resultAlias.YCollection)) // Index was outside the bounds of the array
                .TransformUsing(Transformers.AliasToBean<X>()).List<X>();
    }
}

the results returned have to be grouped with the contents intact (so sql is out since it can only aggregate over the grouped items) but NHibernate can only do this for m,apped entities because there it knows the identity to group by. It is simple to do it manually

Y yAlias = null;
var tempResults = Session.QueryOver<X>()
     .JoinAlias(x => x.YCollection, () => yAlias, JoinType.LeftOuterJoin)
     .SelectList(list => list
         .Select(() => xAlias.Id)
         .Select(() => xAlias.Name)
         ...
         .Select(() => yAlias.Id)
         ...
     .ToList<object[]>()

List<X> results = new List<X>(100); // switch to Hashset if too slow and order does not matter
foreach(var row in tempResults)
{
    Y y = new Y { Id = (long)row[4], ... };
    X x = results.FirstOrDefault(x => x.Id == (long)row[0]));
    if (x != null)
        x.YCollection.Add(y);
    else
        results.Add(new X { Id = (long)row[0], ..., YCollection = { y } };
}

return results;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM