Reputation: 111
It's hard to find how to resolve my issue so I post it here.
public class A
{
public int IdA { get; set; }
public List<AB> ABs { get; set; }
}
public class AB
{
public A ObjectA { get; set; }
public B ObjectB { get; set; }
}
public class B
{
public int IdB { get; set; }
public string Name { get; set; }
}
I would like find a way with QueryOver, to retrieve a list of this DTO
public class DTO
{
public int IdA { get; set; }
public List<string> Names { get; set; }
}
As you can see, I wanted to have all "Name" properties of the object B foreach object B found in my ABs property.
Can you please help me if you know how to do that ?
Upvotes: 1
Views: 3994
Reputation: 126042
There are a few ways to do this, but none that I know of in just QueryOver. You can think of a QueryOver query as translating almost directly to SQL. If you think of it that way, it's impossible to populate a List
property in one step (you couldn't write a SQL query that resulted in an ID and a "list" of items, at least not without using some kind of aggregate).
With that in mind I think it's best here to define a new type of intermediate DTO.
public class FlattenedDTO
{
public int IdA { get; set; }
public string Name { get; set; }
}
Then you'd write your query, projecting out to FlattenedDTO
. After we select out a list of FlattenedDTO
s, we can group them into a new list of DTO
s:
B bAlias = null;
FlattenedDTO result = null;
session.QueryOver<A>()
.JoinQueryOver<AB>(a => a.ABs)
.JoinQueryOver(ab => ab.B, () => bAlias)
.SelectList(list => list
.Select(a => a.Id).WithAlias(() => result.IdA)
.Select(() => bAlias.Name).WithAlias(() => result.Name))
.TransformUsing(Transformers.AliasToBean<FlattenedDTO>())
.List<FlattenedDTO>()
// At this point the query has been run and we just need to group the results
.GroupBy(dto => dto.IdA, dto => dto.Name)
.Select(grp => new DTO { IdA = grp.Key, Names = grp.ToList() });
This will end up issuing one query:
SELECT this_.IdA as y0_,
balias2_.Name as y1_
FROM [A] this_
inner join [AB] ab1_
on this_.Id = ab1_.IdA
inner join [B] balias2_
on ab1_.IdB = balias2_.Id
And grouping the results in memory. There are a few other ways to do this, so let me know if this does not suit your needs.
Upvotes: 2
Reputation: 302
You have to create nhibernate mapping with the table & write a query at there with hbm.xml mapping Like
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NSP.DataModel" namespace="NSP.DataModel.A">
<class name="A" entity-name="SysA" table="A">
<id name="IdA" column="id" type="Int32">
<generator class="identity"/>
</id>
<bag name="DTO" inverse="true">
<key column="IdA"/>
<one-to-many entity-name="Names"/>
</bag>
</class>
</hibernate-mapping>
Upvotes: 1