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.
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..
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.
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.