LINQ to SQL is an ORM (object relational mapping) implementation that ships in the ASP.NET Framework 3.5 release, and which allows you to model a relational database using .NET classes.You can then query the database using LINQ, as well as update/insert/delete data from it. LINQ to SQL provides a runtime infrastructure for managing relational data as objects without losing the ability to query. It does this by translating language-integrated queries into SQL for execution by the database, and then translating the tabular results back into objects you define. Your application is then free to manipulate the objects while LINQ to SQL stays in the background tracking your changes automatically.
LINQ to SQL fully supports transactions, views, and stored procedures.It also provides an easy way to integrate data validation and business logic rules into your data model.
For more information concerning LINQ to SQL review ScottGu's series of blog posts on this subject or the MSDN tutorial linked below:
RadGrid for ASP.NET AJAX exposes programmatic way to binding itself to IEnumerable data returned from LINQ queries which is presented in the following online demo of the product. Additionally, the grid from the example supports manual data editing operations as well as paging and sorting. The main points are to intercept the *NeedDataSource * event to pass a data source to the control and the UpdateCommand, *InsertCommand *and *DeleteCommand *events to edit the data in it.
Here are the code snippets from the example referenced in the previous paragraph (it also demonstrates how to configure *RadInputManager *to manage the user input inside the edit/insert form)
ASP.NET
<telerik:RadCodeBlockID="RadCodeBlock1"runat="server"><scripttype="text/javascript">functionrowDblClick(sender, eventArgs){ sender.get_masterTableView().editItem(eventArgs.get_itemIndexHierarchical());}</script></telerik:RadCodeBlock><telerik:RadAjaxManagerrunat="server"ID="RadAjaxManager1"DefaultLoadingPanelID="RadAjaxLoadingPanel1"><ajaxsettings><telerik:AjaxSettingAjaxControlID="RadGrid1"><UpdatedControls><telerik:AjaxUpdatedControlControlID="RadGrid1"/><telerik:AjaxUpdatedControlControlID="RadWindowManager1"/><telerik:AjaxUpdatedControlControlID="RadInputManager1"/></UpdatedControls></telerik:AjaxSetting></ajaxsettings></telerik:RadAjaxManager><telerik:RadAjaxLoadingPanelrunat="server"ID="RadAjaxLoadingPanel1"/><telerik:RadGridRenderMode="Lightweight"runat="server"ID="RadGrid1"AutoGenerateColumns="false"AllowPaging="true"OnNeedDataSource="RadGrid1_NeedDataSource"OnUpdateCommand="RadGrid1_UpdateCommand"OnItemCreated="RadGrid1_ItemCreated"OnDeleteCommand="RadGrid1_DeleteCommand"OnInsertCommand="RadGrid1_InsertCommand"><mastertableviewdatakeynames="ProductID"commanditemdisplay="Top"insertitempageindexaction="ShowItemOnCurrentPage"><Columns><telerik:GridEditCommandColumnButtonType="ImageButton"/><telerik:GridBoundColumnDataField="ProductID"HeaderText="Product ID"ReadOnly="true"ForceExtractValue="Always"ConvertEmptyStringToNull="true"/><telerik:GridBoundColumnDataField="ProductName"HeaderText="Product Name"/><telerik:GridBoundColumnDataField="UnitsInStock"HeaderText="Units In Stock"/><telerik:GridBoundColumnDataField="UnitPrice"HeaderText="Price"DataFormatString="{0:c}"/><telerik:GridButtonColumnConfirmText="Delete this product?"ConfirmDialogType="RadWindow"ConfirmTitle="Delete"ButtonType="ImageButton"CommandName="Delete"/></Columns><EditFormSettings><EditColumnButtonType="ImageButton"/></EditFormSettings></mastertableview><pagerstylemode="NextPrevAndNumeric"/><clientsettings><ClientEventsOnRowDblClick="rowDblClick"/></clientsettings></telerik:RadGrid><telerik:RadInputManagerRenderMode="Lightweight"runat="server"ID="RadInputManager1"Enabled="true"><telerik:TextBoxSettingBehaviorID="TextBoxSetting1"></telerik:TextBoxSetting><telerik:NumericTextBoxSettingBehaviorID="NumericTextBoxSetting1"Type="Currency"AllowRounding="true"DecimalDigits="2"></telerik:NumericTextBoxSetting><telerik:NumericTextBoxSettingBehaviorID="NumericTextBoxSetting2"Type="Number"AllowRounding="true"DecimalDigits="0"MinValue="0"></telerik:NumericTextBoxSetting></telerik:RadInputManager><telerik:RadWindowManagerRenderMode="Lightweight"ID="RadWindowManager1"runat="server"/>
C#
privateNorthwindDataContext _dataContext;protectedNorthwindDataContext DbContext
{get{if(_dataContext ==null){
_dataContext =newNorthwindDataContext();}return _dataContext;}}publicoverridevoidDispose(){if(_dataContext !=null){
_dataContext.Dispose();}base.Dispose();}protectedvoidRadGrid1_NeedDataSource(object source,GridNeedDataSourceEventArgs e){
RadGrid1.DataSource = DbContext.Products;}protectedvoidRadGrid1_UpdateCommand(object source,GridCommandEventArgs e){var editableItem =((GridEditableItem)e.Item);var productId =(int)editableItem.GetDataKeyValue("ProductID");//retrive entity form the Db var product = DbContext.Products.Where(n => n.ProductID == productId).FirstOrDefault();if(product !=null){//update entity's state
editableItem.UpdateValues(product);try{//submit chanages to Db
DbContext.SubmitChanges();}catch(System.Exception){ShowErrorMessage();}}}privatevoidShowErrorMessage(){
RadAjaxManager1.ResponseScripts.Add(string.Format("window.radalert(\"Please enter valid data!\")"));}protectedvoidRadGrid1_ItemCreated(object sender,GridItemEventArgs e){if(e.Item isGridEditableItem&&(e.Item.IsInEditMode)){GridEditableItem editableItem =(GridEditableItem)e.Item;SetupInputManager(editableItem);}}privatevoidSetupInputManager(GridEditableItem editableItem){// style and set ProductName column's textbox as required var textBox =((GridTextBoxColumnEditor)editableItem.EditManager.GetColumnEditor("ProductName")).TextBoxControl;
textBox.ID ="TextBox1";InputSetting inputSetting = RadInputManager1.GetSettingByBehaviorID("TextBoxSetting1");
inputSetting.TargetControls.Add(newTargetInput(textBox.UniqueID,true));
inputSetting.InitializeOnClient =true;
inputSetting.Validation.IsRequired =true;// style UnitPrice column's textbox
textBox =((GridTextBoxColumnEditor)editableItem.EditManager.GetColumnEditor("UnitPrice")).TextBoxControl;
textBox.ID ="TextBox2";
inputSetting = RadInputManager1.GetSettingByBehaviorID("NumericTextBoxSetting1");
inputSetting.InitializeOnClient =true;
inputSetting.TargetControls.Add(newTargetInput(textBox.UniqueID,true));// style UnitsInStock column's textbox
textBox =((GridTextBoxColumnEditor)editableItem.EditManager.GetColumnEditor("UnitsInStock")).TextBoxControl;
textBox.ID ="TextBox3";
inputSetting = RadInputManager1.GetSettingByBehaviorID("NumericTextBoxSetting2");
inputSetting.InitializeOnClient =true;
inputSetting.TargetControls.Add(newTargetInput(textBox.UniqueID,true));}protectedvoidRadGrid1_InsertCommand(object source,GridCommandEventArgs e){var editableItem =((GridEditableItem)e.Item);//create new entity var product =newLinqToSql.Product();//populate its properties Hashtable values =newHashtable();
editableItem.ExtractValues(values);
product.ProductName =(string)values["ProductName"];if(values["UnitsInStock"]!=null){
product.UnitsInStock =short.Parse(values["UnitsInStock"].ToString());}if(values["UnitPrice"]!=null){
product.UnitPrice =decimal.Parse(values["UnitPrice"].ToString());}
DbContext.Products.InsertOnSubmit(product);try{//submit chanages to Db
DbContext.SubmitChanges();}catch(System.Exception){ShowErrorMessage();}}protectedvoidRadGrid1_DeleteCommand(object source,GridCommandEventArgs e){var productId =(int)((GridDataItem)e.Item).GetDataKeyValue("ProductID");//retrive entity form the Db var product = DbContext.Products.Where(n => n.ProductID == productId).FirstOrDefault();if(product !=null){//add the category for deletion
DbContext.Products.DeleteOnSubmit(product);try{//submit chanages to Db
DbContext.SubmitChanges();}catch(System.Exception){ShowErrorMessage();}}}
VB
Private _dataContext As NorthwindDataContext
ProtectedReadOnlyProperty DbContext()As NorthwindDataContext
GetIf _dataContext IsNothingThen
_dataContext =New NorthwindDataContext()EndIfReturn _dataContext
EndGetEndPropertyPublicOverloadsOverridesSub Dispose()If _dataContext IsNotNothingThen
_dataContext.Dispose()EndIfMyBase.Dispose()EndSubProtectedSub RadGrid1_NeedDataSource(ByVal source AsObject,ByVal e As GridNeedDataSourceEventArgs)Handles RadGrid1.NeedDataSource
RadGrid1.DataSource = DbContext.Products
EndSubProtectedSub RadGrid1_UpdateCommand(ByVal source AsObject,ByVal e As GridCommandEventArgs)Handles RadGrid1.UpdateCommand
Dim editableItem =(DirectCast(e.Item, GridEditableItem))Dim productId =DirectCast(editableItem.GetDataKeyValue("ProductID"),Integer)'retrive entity form the DbDim product = DbContext.Products.Where(Function(n) n.ProductID = productId).FirstOrDefault()If product IsNotNothingThen'update entity's state
editableItem.UpdateValues(product)Try'submit chanages to Db
DbContext.SubmitChanges()Catch generatedExceptionName AsSystem.Exception
ShowErrorMessage()EndTryEndIfEndSubPrivateSub ShowErrorMessage()
RadAjaxManager1.ResponseScripts.Add(String.Format("window.radalert(""Please enter valid data!"")"))EndSubProtectedSub RadGrid1_ItemCreated(ByVal sender AsObject,ByVal e As GridItemEventArgs)Handles RadGrid1.ItemCreated
IfTypeOf e.Item Is GridEditableItem AndAlso(e.Item.IsInEditMode)ThenDim editableItem As GridEditableItem =DirectCast(e.Item, GridEditableItem)
SetupInputManager(editableItem)EndIfEndSubPrivateSub SetupInputManager(ByVal editableItem As GridEditableItem)' style and set ProductName column's textbox as requiredDim textBox =(DirectCast(editableItem.EditManager.GetColumnEditor("ProductName"), GridTextBoxColumnEditor)).TextBoxControl
textBox.ID ="TextBox1"Dim inputSetting As InputSetting = RadInputManager1.GetSettingByBehaviorID("TextBoxSetting1")
inputSetting.TargetControls.Add(New TargetInput(textBox.UniqueID,True))
inputSetting.InitializeOnClient =True
inputSetting.Validation.IsRequired =True' style UnitPrice column's textbox
textBox =(DirectCast(editableItem.EditManager.GetColumnEditor("UnitPrice"), GridTextBoxColumnEditor)).TextBoxControl
textBox.ID ="TextBox2"
inputSetting = RadInputManager1.GetSettingByBehaviorID("NumericTextBoxSetting1")
inputSetting.InitializeOnClient =True
inputSetting.TargetControls.Add(New TargetInput(textBox.UniqueID,True))' style UnitsInStock column's textbox
textBox =(DirectCast(editableItem.EditManager.GetColumnEditor("UnitsInStock"), GridTextBoxColumnEditor)).TextBoxControl
textBox.ID ="TextBox3"
inputSetting = RadInputManager1.GetSettingByBehaviorID("NumericTextBoxSetting2")
inputSetting.InitializeOnClient =True
inputSetting.TargetControls.Add(New TargetInput(textBox.UniqueID,True))EndSubProtectedSub RadGrid1_InsertCommand(ByVal source AsObject,ByVal e As GridCommandEventArgs)Handles RadGrid1.InsertCommand
Dim editableItem =(DirectCast(e.Item, GridEditableItem))'create new entityDim product =New LinqToSql.Product()'populate its propertiesDim values AsNew Hashtable()
editableItem.ExtractValues(values)
product.ProductName =DirectCast(values("ProductName"),String)If values("UnitsInStock")IsNotNothingThen
product.UnitsInStock =Short.Parse(values("UnitsInStock").ToString())EndIfIf values("UnitPrice")IsNotNothingThen
product.UnitPrice =Decimal.Parse(values("UnitPrice").ToString())EndIf
DbContext.Products.InsertOnSubmit(product)Try'submit chanages to Db
DbContext.SubmitChanges()Catch generatedExceptionName AsSystem.Exception
ShowErrorMessage()EndTryEndSubProtectedSub RadGrid1_DeleteCommand(ByVal source AsObject,ByVal e As GridCommandEventArgs)Handles RadGrid1.DeleteCommand
Dim productId =DirectCast((DirectCast(e.Item, GridDataItem)).GetDataKeyValue("ProductID"),Integer)'retrive entity form the DbDim product = DbContext.Products.Where(Function(n) n.ProductID = productId).FirstOrDefault()If product IsNotNothingThen'add the product for deletion
DbContext.Products.DeleteOnSubmit(product)Try'submit chanages to Db
DbContext.SubmitChanges()Catch generatedExceptionName AsSystem.Exception
ShowErrorMessage()EndTryEndIfEndSub