Using 2 Tables Joined with LINQ as data source without anonymous cast error in databond method

Yesterday one of our project team member faced a challenge of using an anonymous data that is returned from joining 2 typed data tables with LINQ. The problem is not how to use the data, the problem was how to be able to cast and use the data in Repeater ItemDataBond method without having “<>f__AnonymousType0….” cast error. below is the join query (tables used are typed) :-

   1:PagedDataSource objPDS = new PagedDataSource();
   2:objPDS.AllowPaging = true;
   3:objPDS.PageSize = 10;
   4:   
   5:objPDS.DataSource = (from p in Table1
   6:                join  d in Table2 on p.ID equals d.ID
   7:                               select new
   8:                               {   
   9:                                   p,
  10:                                   F1= d.f1,
  11:                                   F2= d.f2,
  12:                                   F3= d.f3,
  13:                                   F4= d.f4,
  14:                                 }).ToList();

The code above will return rows with anonymous type that will include fields wanted for table2 and all table1 fields!.
NOTACE : to bind this data to repeater use <%# Eval("F1”) %> for Table2 fields and <%# Eval("p.FieldName”) %> for Table1 Fields.

Now what will happen if we want to use the datarow data bonded to repeater row! the code below will show you that you can not cast that datasource in ItemDataBond method as DataRowView :-

   1:  var bindedRow= e.Item.DataItem as DataRowView; 
   2:  //bindedRow return null value

So how to use a value inside the bonded row! after some researches I found out that reflection must be used to take that value from e.Item.DataItem with anonymous data. Reflection can be done by using DataBind.Eval which will evaluate data at run time. A label added to repeater and we want to bond some data at itemdatabond time, the code below will demonstrate that :- (Sorry for using multiline in code)

   1:  label1.Text = Table3.
   2:  Where(cid => cid.ID == 
           (Guid)DataBinder.
Eval(e.Item.DataItem, "p.FieldName")).
   3:  First().ToString();

DataBind.Eval Done the trick for you and retrieve wonted data from the anonymous type and casting it to needed type (here its guid).

Hope this Helps

No Comments