LinqDataSouce - DataItem in code behind - Raj Kaimal

LinqDataSouce - DataItem in code behind

Version : Visual Studio 2008 Beta 2

The following examples shows how to use the GridViewRow.DataItem property to retrieve a property of the underlying object to which the GridViewRow is bound when using the LinqDataSource control.

I have a GridView whose DataSouce is a LinqDataSource. The LinqDataSource has been set to retrieve all records from the Product entity in the Northwind Linq to SQL data model like so:

 1: <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="LinqDataSource1"
 2: OnRowDataBound="GridView1_RowDataBound">
 3: <Columns>
 4: <asp:BoundField DataField="ProductID" HeaderText="ProductID" ReadOnly="True"></asp:BoundField>
 5: <asp:BoundField DataField="ProductName" HeaderText="ProductName" ReadOnly="True"></asp:BoundField>
 6: </Columns>
 7: </asp:GridView>
 8: <asp:LinqDataSource ID="LinqDataSource1" runat="server" ContextTypeName="NorthwindDataContext"
 9: TableName="Products">
 10: </asp:LinqDataSource>

In this case, getting a property of the underlying data object is easy. The LinqDataSource is aware that each object in the result set is of Type Product (as defined in the Linq to SQL class) and creates it accordingly. So all we have to do is cast the DataItem to type Product and then retrieve the productName:

 1: protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
 2: {
 3: if (e.Row.RowType == DataControlRowType.DataRow)
 4: {
 5: Product p = (Product) e.Row.DataItem;
 6: string productName = p.ProductName;
 7: }
 8: }

The LinqDataSource also allows you to shape the data that is retrieved. In the example below,  I have specified a declarative select to retrieve only a subset of the values from the Products entity - the ProductID and ProductName.

 1: <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="LinqDataSource1"
 2: OnRowDataBound="GridView1_RowDataBound">
 3: <Columns>
 4: <asp:BoundField DataField="ProductID" HeaderText="ProductID" ReadOnly="True"></asp:BoundField>
 5: <asp:BoundField DataField="ProductName" HeaderText="ProductName" ReadOnly="True"></asp:BoundField>
 6: </Columns>
 7: </asp:GridView>
 8: <asp:LinqDataSource ID="LinqDataSource1" runat="server" ContextTypeName="NorthwindDataContext"
 9: Select="new (ProductID, ProductName)" TableName="Products">
 10: </asp:LinqDataSource>

Since we have defined a custom shape for our result, the LinqDataSouce will create an anonymous type for each object in the resultset like so:

 1: x = {ProductID=17, ProductName=Alice Mutton}

Since we do not know what type to cast the DataItem to, we can use Reflection to retrieve the property. The DataBinder.Eval method already does this so we can retrieve the productName like so:

 1: protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
 2: {
 3: if (e.Row.RowType == DataControlRowType.DataRow)
 4: {
 5: var x = e.Row.DataItem;
 6: string productName = (string) DataBinder.Eval(e.Row.DataItem, "ProductName");
 7: }
 8: }

If you know of a non reflection or better way, please post a comment.

Published Tuesday, September 18, 2007 11:40 PM by rajbk
Filed under: , ,

Comments

# re: LinqDataSouce - DataItem in code behind

I have been looking for a way to do this, thanks!

Friday, October 05, 2007 9:02 PM by Vinay

# 101 LINQ Beispiele und weitere Links

Vor einer Weile hatte ich hier einen Beitrag zu den LINQ to SQL Tutorials von Scott Guthrie (1) veröffentlicht.

Wednesday, October 24, 2007 3:24 AM by Jürgen Gutsch

# re: LinqDataSouce - DataItem in code behind

A very useful gem of information for those of us used to using the likes of DataItem("ProductName") who have bumped into "No default member found for type 'VB$AnonymousType_0(Of ...)'." when shaping a linq query (from VB).

Saturday, February 23, 2008 9:13 AM by Martin G C Davies

# re: LinqDataSouce - DataItem in code behind

Thank you, I was looking for a way to do this!  Very helpful.

Friday, March 14, 2008 11:39 AM by Chris

# re: LinqDataSouce - DataItem in code behind

I tried Product p = (Product) e.Row.DataItem; and got the error

Unable to cast object of type 'DynamicClass1' to type 'Product'.

Please help

Friday, June 06, 2008 5:12 AM by anzer

# re: LinqDataSouce - DataItem in code behind

Thanks! Helped me alot!

Thursday, June 12, 2008 8:05 AM by grl

# re: LinqDataSouce - DataItem in code behind

Thanks!  I was scratching my head with a "Unable to cast object of type 'DynamicClass1' to type 'System.Data.DatarowView' all day yesterday.  Your article saved my butt!  

Now instead of:

e.Item.Text=((DataRowView)e.Item.DataItem)["Description'].ToString();

I have:

e.Item.Text=(string)DataBinder.Eval(e.Item.DataItem, "Description");

It works like a carm!

Wednesday, July 02, 2008 9:00 AM by Richard Elliott

# re: LinqDataSouce - DataItem in code behind

Man, this just rocked my world... how simple to do, but so effen hard to find... thanks

retrieve dataitem value from LINQ queries

Wednesday, April 15, 2009 4:01 AM by ramon

# re: LinqDataSouce - DataItem in code behind

Just the clear answer I required - Thanks

Friday, July 03, 2009 10:02 AM by ENF

# re: LinqDataSouce - DataItem in code behind

Thanks for the tip!!

Tuesday, October 27, 2009 9:27 AM by Dean Brophy

# LinqDataSouce &#8211; DataItem in code behind &laquo; Usman&#039;s Blog

Pingback from  LinqDataSouce &#8211; DataItem in code behind &laquo;  Usman&#039;s Blog

Monday, November 16, 2009 2:08 AM by LinqDataSouce – DataItem in code behind « Usman's Blog

Leave a Comment

(required) 
(required) 
(optional)
(required)