title: NHibernate code mapping bag join two tables
body: <p>I have the following definition for a Transaction (as in purchase details) object : </p>
  
  <pre><code>public class Transaction : MappingObject
  {
      public virtual int Id { get; set; }
      public virtual IList&lt;TransactionProduct&gt; Products { get; set; }
  }
  
  public class TransactionMap : ClassMapping&lt;Transaction&gt;
  {
      public TransactionMap()
      {
          Table("TRANSACTIONS_TBL");
          Id(x =&gt; x.Id, m =&gt;
          {
              m.Column("ID");
              m.Generator(Generators.Identity);
          });
          Bag(x =&gt; x.Products, m =&gt;
          {
              m.Inverse(true);
              m.Table("TRANSACTION_PRODUCTS_TBL");
              m.Key(k =&gt; k.Column("TRANSACTION_ID"));
              m.Lazy(CollectionLazy.NoLazy);
          }, 
          relation =&gt; relation.OneToMany(mapper =&gt; mapper.Class(typeof(TransactionProduct))));
      }
  }
  </code></pre>
  
  <p>And TransactionProduct is defined like this : </p>
  
  <pre><code>public class TransactionProduct : MappingObject
  {
      public virtual int TransactionId { get; set; }
      public virtual int ProductId { get; set; }
      public virtual int Quantity { get; set; }
  
      public override bool Equals(object obj)
      {
          var t = obj as TransactionProduct;
          if (t == null)
              return false;
          if (TransactionId == t.TransactionId &amp;&amp; ProductId == t.ProductId)
              return true;
          return false;
      }
      public override int GetHashCode()
      {
          return (TransactionId + "|" + ProductId).GetHashCode();
      }
  }
  
  public class TransactionProductMap : ClassMapping&lt;TransactionProduct&gt;
  {
      public TransactionProductMap()
      {
          Table("TRANSACTION_PRODUCTS_TBL");
          ComposedId(map =&gt;
          {
              map.Property(x =&gt; x.TransactionId, m =&gt; m.Column("TRANSACTION_ID"));
              map.Property(x =&gt; x.ProductId, m =&gt; m.Column("PRODUCT_ID"));
          });
          Property(x =&gt; x.Quantity, m =&gt; m.Column("QUANTITY"));
      }
  }
  </code></pre>
  
  <p>Now, I want to select a transaction and populate the Products array in a single select (I know I can select the transaction then the products but It's bad practice)</p>
  
  <p>So I'm using this : </p>
  
  <pre><code>        using (var session = CommonDAL.GetSession())
          {
              Transaction transactionAlias = null;
              TransactionProduct transactionProductAlias = null;
  
              return session.QueryOver(() =&gt; transactionAlias).
                  JoinAlias(() =&gt; transactionAlias.Products, () =&gt; transactionProductAlias).
                  Where(() =&gt; transactionAlias.Id == transactionProductAlias.TransactionId).List().ToList();
          }
  </code></pre>
  
  <p>This work's quite well but the problem is that if I have a transaction with 2 products, I get 2 transaction objects with 2 products inside them, same goes for if I have a transaction with 4 products, I get 4 transaction objects with 4 products. The transaction objects are good, but the problem is the duplicates.</p>
  
  <p>I can probably solve it with Distinct() but again, I want best practice</p>