A LINQ óriási előnye, hogy a relációs adatainkat szinte észrevétlenül fordítja át objektumok halmazára, emiatt a LinqDataSource inkább rokon az ObjectDataSource vezérlővel, mint az SqlDataSource-szal. Íme egy példa ennek illusztrálására.
Vegyük a Northwind adatbázis Products tábláját és egy SqlDataSource segítségével jelenítsük meg belőle a ProductID és ProductName mezőket, valahogy így:
<asp:GridView ID="gvProducts" runat="server"
DataKeyNames="ProductID" DataSourceID="sdsProducts"
AutoGenerateColumns="false" onrowdatabound="gvProducts_RowDataBound">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="Azonosító" />
<asp:HyperLinkField
DataNavigateUrlFields="ProductID"
DataNavigateUrlFormatString="Products.aspx?id={0}"
DataTextField="ProductName"
HeaderText="Termék" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsProducts" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="SELECT * FROM [Products]" />
Legyen az a feladat, hogy a ProductName mező linkként viselkedjen, ha a Discontinued mező értéke true, egyébként pedig csak jelenjen meg a termék neve, de ne legyen kattintható. Ezért a ProductName mező megjelenítéséhez HyperLinkFieldet használtam és hozzárendeltem egy eseménykezelőt a RowDataBound eseményhez. Ebben az eseménykezelőben az a cél, hogy megszerezzük a Discontinued mező értékét, ami nekem csak elég körülményesen sikerült:
protected void gvProducts_RowDataBound( object sender, GridViewRowEventArgs e )
{
if( e.Row.RowType == DataControlRowType.DataRow )
{
DataRowView row = (DataRowView) e.Row.DataItem;
int productID = (int) row[ "ProductID" ];
// Product megszerzése ProductID alapján...
}
}
Látható, hogy bár burkoltan, de még mindig rekordokkal kell bajlódni.
Próbáljuk ki mindezt egy LinqDataSource segítségével:
<asp:LinqDataSource ID="ldsNorthwind" runat="server"
ContextTypeName="NorthwindDataContext"
TableName="Products">
</asp:LinqDataSource>
Mivel a LinqDataSource már objektumokat köt, az eseménykezelőnk lényegesen egyszerűbb:
protected void gvProducts_RowDataBound( object sender, GridViewRowEventArgs e )
{
if( e.Row.RowType == DataControlRowType.DataRow )
{
Product p = (Product) e.Row.DataItem;
if( p.Discontinued )
{
HyperLink hl = e.Row.Cells[ 1 ].Controls[ 0 ] as HyperLink;
hl.NavigateUrl = String.Empty;
}
}
}
Ebben a megközelítésben tehát teljesen elfelejthetjük a rekordokat, objektum gyűjteményekkel dolgozunk, mint az ObjectDataSource esetén. Nem tudom, ki hogyan van vele, nekem ez így szimpatikusabb.
Kiegészítettem a korábbi példát, így már ennek a forrása is megtalálható benne.