-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: displaying 2 fields from different classes with join
PostPosted: Wed Jun 22, 2005 11:28 pm 
Newbie

Joined: Wed Jun 22, 2005 10:34 pm
Posts: 3
Hi all,

Need help with hql.

SELECT u FROM User AS u INNER JOIN u.UserRole AS role

The query above works fine however if I ONLY want to display 2 fields from Users and UserRole the result returned are the properties of an ArrayList/IList??? My query is like this:

SELECT u.LastName, role.Role FROM User AS u INNER JOIN u.UserRole AS role

Thanks,
Chris


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 23, 2005 12:30 am 
Newbie

Joined: Fri May 13, 2005 7:46 pm
Posts: 17
Your HQL is fine. I would prefer something like:

"select u.LastName, u.UserRole.Role from User as u"

It seems a little more clear/concise to me, but they both do the same thing pretty much so no biggie, like I said it's fine.

The problem is that when you query on properties like this what you get back is an array of arrays. Or rather an IList of (I think) string arrays (though I could be wrong and the inner array is one of object[] with properly typed items).

So when you try to bind to a WebForms DataGrid for example, and it reflects over the collection, it decides it doesn't know what to do with the inner array, so it just displays the properties of the IList as if you had bound any type of single object.

What you need to do is convert that into an ITypedList such as a DataView or DataTable.

Code:
IList results = session.Find("select u.LastName, u.UserRole.Role from User as u");

DataTable table = new DataTable();
table.Columns.Add("Last Name");
table.Columns.Add("Role");

foreach(object[] objects in results) {
   table.Rows.Add(objects); // I *think* .Add() can take an array to create a row, but maybe not.
}

myGrid.DataSource = table.DefaultView;
myGrid.DataBind();


Of course the above isn't gauranteed to build, but it should be close.

Kinda gimpy huh? Personally, I made a class to handle this. You might call it something like TypedListGenerator (I called mine ObjectView, but that's a dumb name considering it's not really. For a proper one checkout a project of that name by one of the Contrib authors (sorry, forgot who)).

An implementation might look like this:

Code:
public class TypedListGenerator {
   public TypedListGenerator(IList nestedArrays) {
      this._nestedArrays = nestedArrays;
      this._view = new DataTable();
   }
   
   IList _nestedArrays;
   DataTable _view;
   
   public void AddColumn(string name) {
      this.AddColumn(name, typeof(String));
   }
   
   public void AddColumn(string name, Type type) {
      this._view.Columns.Add(name, type);
   }
   
   public ITypedList Format() {
      if(this._view.Rows.Count != this._nestedArrays.Count) {
         foreach(object[] row in this._nestedArrays) {
            this._view.Rows.Add(row);
         }
      }
      
      return this._view.DefaultView;
   }   
}


Of course someone probably has a better idea (if you do I'd be interested to hear it!), but this has worked out well for me so far, so hopefully it points ya in the right direction. This would make your code look like this:

Code:
IList results = session.Find("select u.LastName, u.UserRole.Role from User as u");

TypedListGenerator tableView = new TypedListGenerator(results);

tableView.AddColumn("Last Name");
tableView.AddColumn("Role");

myGrid.DataSource = tableView.Format();
myGrid.DataBind();


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jun 23, 2005 1:38 am 
Newbie

Joined: Wed Jun 22, 2005 10:34 pm
Posts: 3
Got it now! Thanks!


Top
 Profile  
 
 Post subject: TypedListGenerator/ObjectView
PostPosted: Thu Jun 23, 2005 6:52 am 
Newbie

Joined: Wed Jun 22, 2005 10:34 pm
Posts: 3
Ok, so I made something like an ObjectView BUT Im returning a DataTable. Here is my code:


Code:
public class NhQueryHelper
   {
      IQuery _query;
      ArrayList _columns;

      public NhQueryHelper(IQuery query)
      {
         _query = query;
         _columns = new ArrayList();
      }

      public void AddColumn(string name)
      {
         _columns.Add(name);
      }


      public DataTable ObjectView()
      {
         const string colName = "Field";
         DataTable dt = null;

         if (_query == null)
            return null;

         dt = new DataTable();
         
         for (int i = 0; i < _query.ReturnTypes.Length; i++)
         {
            IType type = _query.ReturnTypes[i];
            
            if (_columns.Count == 0)
            {
               dt.Columns.Add(string.Format("{0}{1}", colName, i), type.ReturnedClass);
            }
            else
            {
               if (i < _columns.Count)
                  dt.Columns.Add(_columns[i].ToString(), type.ReturnedClass);
               else
                  dt.Columns.Add(string.Format("{0}{1}", colName, i), type.ReturnedClass);
            }
         }

         IList list = _query.List();

         for (int i = 0; i < list.Count; i++)
         {
            DataRow row = dt.NewRow();
            object[] records = (object[])list[i];

            for (int j = 0; j < records.Length; j++)
            {
               row[dt.Columns[j].ColumnName] = records[j];
            }
            dt.Rows.Add(row);
         }

         return dt;
      }
   }


Is the what you are doing also when you want to bind on a grid?


Many thanks!

Chris
--


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.