Question

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 ?

Était-ce utile?

La solution

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 FlattenedDTOs, we can group them into a new list of DTOs:

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.

Autres conseils

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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top