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();