I am binding a grid to a linq statement which creates an anonymous type class for the data. When I try and get to the data in the InitializeRow event, I'm having a problem casting the row properly. If I create a class for the linq results, it's easy, but I don't want to create a new class for every linq statement. For example:
var rows= from r in db.table select new {id=xxxx, value=yyyy} <-- this creates an anonymous type versus....
var rows= from r in db.table select rowclass new {id=xxxx, value=yyyy}
class rowclass {int id, string yyyy}, which gives me a collection of rowclass.
Any ideas on how to access the data when using anonymous classes? thanks.
Yes, I also believe this is the best approach in this case. I was also able to confirm that the built-in asp:GridView passes anonymous types the same way UltraWebGrid does, so this appears to be a generic LINQ case.
Maybe guys with more LINQ experience / anonymous types experience will be able to add more to this discussion.
Meanwhile I found the following blog post by Scott Guthrie (PM of the ASP.NET framework) very good and informative regarding LINQ/Anonymous types.
http://weblogs.asp.net/scottgu/archive/2007/05/15/new-orcas-language-feature-anonymous-types.aspx?CommentPosted=true
Hope this helps.
Rumen:
Well, that's exactly the problem I'm having too, and I agree, the reflection probably isn't worth it. My simple solution was to create a concrete class so that I can cast e.Data to it. Works nicely, but not my favorite way to do this.
Thanks for the input.
I need to get to some of the data columns that are not bound to grid columns. So i need to use e.Data instead of e.Row.
A very interesting case, thanks for sharing in forums. I also reproduced something similar to that, based on simple SQL data. Here is my setup based on a simple datatable with ID (int) and Name (string) columns:
<igtbl:UltraWebGrid ID="UltraWebGrid1" runat="server" oninitializerow="UltraWebGrid1_InitializeRow">
and here is my binding code:
{ protected void Page_Load(object sender, EventArgs e) { DataClassesDataContext dataContext = new DataClassesDataContext(); var industries = from p in dataContext.Industries select new { ID = p.ID, Name = p.Name }; UltraWebGrid1.DataSource = industries; UltraWebGrid1.DataBind(); }
If I am using anonymous types, e.Data.GetType() in the oninitializerow event handler returns the following type:
{Name = "<>f__AnonymousType0`2" FullName = "<>f__AnonymousType0`2[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"} System.Type {System.RuntimeType}
No matter what I tried, I was not able to find an elegant way to retrieve ID and Name there. I guess, this is by design in the .NET Framework - if we are using anonymous types, we are just using them for binding and not in code-behind and this is how we achieve the speed upgrade of anonymous types. If we do need to use the data in code-behind, then we must resort to classes/instances.
By the way, I was still able to get ID/Name for anonymous types in oninitializerow, however I am using reflection, and I am not sure that the cost of using reflection makes this approach useless (and it is a little bit ugly approach).
protected void UltraWebGrid1_InitializeRow(object sender, Infragistics.WebUI.UltraWebGrid.RowEventArgs e) { PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(e.Data); int id = (int) pdc["ID"].GetValue(e.Data); string name = pdc["Name"].GetValue(e.Data) as string; }
You can also try to obtain ID / Name directly from the Cells of the Row - they should already be available in InitializeRow.
If you believe this approach is applicable, let us know. Any other ideas on this interesting topic are more than welcome..
Not sure exactly what you are trying to do, but I have some code which needs to get access to the row data in the InitializeRow event.
I simply use code like
dim strName as string = e.row.Cells(0).Text
This returns the string in the first column of the row.
This code works for a LINQ query from both XML and SQL.
Not sure if this of any help
Alex