{"id":4883,"date":"2007-12-27T22:55:00","date_gmt":"2007-12-27T22:55:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/12\/27\/linq-for-the-web-using-vb-by-paul-yuknewicz\/"},"modified":"2024-07-05T14:35:20","modified_gmt":"2024-07-05T21:35:20","slug":"linq-for-the-web-using-vb-by-paul-yuknewicz","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/linq-for-the-web-using-vb-by-paul-yuknewicz\/","title":{"rendered":"LINQ for the Web Using VB (By Paul Yuknewicz)"},"content":{"rendered":"<p>Happy holidays!&nbsp; It&#8217;s been a long time since I&#8217;ve written a post, so I figure I can bring in the new year answering some great questions&nbsp;submitted by&nbsp;you.&nbsp; <\/p>\n<p>Just this week someone gave me this feedback: <br \/><em><strong>&#8220;I am having a difficult time finding information to help me adapt to LINQ in my webforms. I am hoping that someone from the team can offer a direction. &#8220;<\/strong><\/em><\/p>\n<p>You bet!&nbsp; We have a lot of attention to LINQ and Forms-over-data in VB in our <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/vbasic\/ms789086.aspx\">learning content<\/a>, but we&#8217;re lacking content with attention to LINQ and Web-based Forms-over-data.&nbsp; <\/p>\n<p>There are a number of great innovations in the Web space that make it easy to leverage LINQ&#8217;s querying capabilities and mesh that with the richness and flexibility of Web-based UI.&nbsp; <em>It&#8217;s easy.<\/em>&nbsp; <\/p>\n<p>There are a few concepts you should learn or know about to get started:<\/p>\n<ul>\n<li><strong>LinqDataSource control<\/strong> &#8212; allows you to use a LINQ query as a data source in Web-based data binding <\/li>\n<li><strong>LinqDataSource.Selecting event <\/strong>&#8211; allows you to set any LINQ custom query (including anonymous queries) as the data source.&nbsp; Simply pick LinqDataSource and Selecting events from the VB editor dropdowns, and set e.Result = &lt;your LINQ query&gt; in the event handler code <\/li>\n<li><strong>OR Designer and Linq to SQL<\/strong> &#8211; if you&#8217;re connecting directly to a SQL database with your LINQ query (instead of objects, xml, etc), this is an easy way to create queries and what we call DataContext objects.&nbsp; &#8220;OR&#8221; is short for Object-Relational mapping, i.e. mapping relational database data to .NET objects <\/li>\n<li><strong>ASP.NET data binding expressions<\/strong> &#8211; allows you to evaluate&nbsp;ASP-style &lt;%# Eval(&#8220;YOURFIELD&#8221;) %&gt; expressions from data source fields or properties in simple controls or lists of controls <\/li>\n<\/ul>\n<h3>Creating a Simple Web Form with LINQ To SQL<\/h3>\n<p>The first post will cover the simplest Web form that will demonstrate this end to end span of concepts.&nbsp; I&#8217;ll then take input from you to add features and expand on this sample in future posts.&nbsp; <\/p>\n<p>Here&#8217;s a sample of the initial desired Web form output &#8211; a very simple Employee list report for an HR application &#8211; admittedly it&#8217;s bare bones and in need of UI design love:<\/p>\n<blockquote>\n<p><em><font color=\"#8080c0\"><img decoding=\"async\" alt=\"Photo Number XXX\" src=\"\"> <br \/>EmployeeID: 2 <br \/>Andrew Fuller <br \/>Andrew received his BTS commercial in 1974 and a Ph.D. in international marketing from the University of Dallas in 1981. He is fluent in French and Italian and reads German. He joined the company as a sales representative, was promoted to sales manager in January 1992 and to vice president of sales in March 1993. Andrew is a member of the Sales Management Roundtable, the Seattle Chamber of Commerce, and the Pacific Rim Importers Association.<\/font><\/em><\/p>\n<p><em><font color=\"#8080c0\"><img decoding=\"async\" alt=\"Photo Number XXX\" src=\"\"> <br \/>EmployeeID: 1 <br \/>Nancy Davolio <br \/>Education includes a BA in psychology from Colorado State University in 1970. She also completed &#8220;The Art of the Cold Call.&#8221; Nancy is a member of Toastmasters International.<\/font><\/em><\/p>\n<\/blockquote>\n<p>If you are pretty familiar with Visual Studio I expect this will take about 10-15 minutes to walk through on your own machine.&nbsp; <\/p>\n<h5>Preparation<\/h5>\n<p>&#8211; make sure you have Visual Studio&nbsp;2008 or Visual Web Developer 2008&nbsp;Express installed.&nbsp; Express Editions are <a href=\"http:\/\/www.microsoft.com\/express\/download\/default.aspx\">available for download here<\/a>. <br \/>&#8211; make sure you have SQL Server 2005 Express installed and running.&nbsp; It typically gets installed by default with VS or VS Express, however, you can also <a href=\"http:\/\/www.microsoft.com\/express\/download\/default.aspx\">install it from here<\/a>.&nbsp; <br \/>-if you don&#8217;t have Northwind.mdf on your machine, download it from the attached files on this post.&nbsp; <\/p>\n<h5>Adding Data to the Web Site<\/h5>\n<p>First we&#8217;re going to add the database to our project and create necessary classes to use the database in LINQ (using Linq to SQL).&nbsp; <em>Note, you could choose to skip this step and create your own custom LINQ query to any other data source.<\/em>&nbsp; <\/p>\n<ol>\n<li>create a new Web site on the local file system via File -&gt; New Web Site &#8230; -&gt; ASP.NET Web Site <\/li>\n<li>add the Northwind database to your web site&#8217;s App_Data folder\n<ol>\n<li>download Northwind.mdf file from this blog entry and save it to disk <\/li>\n<li>drag and drop this file into the App_Data folder in Solution Explorer <br \/>&nbsp;<a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/1AddLocalDatabase_4.jpg\"><img decoding=\"async\" height=\"244\" alt=\"1AddLocalDatabase\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/12\/1AddLocalDatabase_thumb_1.jpg\" width=\"150\" border=\"0\"><\/a> <\/li>\n<\/ol>\n<\/li>\n<li>Create LINQ to SQL classes for Northwind using the OR Designer.&nbsp; Linq to SQL classes will be stored in a .dbml file and can be opened in the visual OR Designer.&nbsp;\n<ol>\n<li>Right-click on the WebSite node in Solution Explorer, <strong>Add New Item -&gt; Linq To SQL Classes<\/strong> <\/li>\n<li><strong>Rename<\/strong> the file from &#8220;DataClasses.dbml&#8221; to &#8220;<strong>Northwind<\/strong>DataClasses.dbml&#8221;.&nbsp; (This is important so classes can be found in code and in VS wizards). <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/2AddLinqToSqlClasses_2.jpg\"><img decoding=\"async\" height=\"315\" alt=\"2AddLinqToSqlClasses\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/12\/2AddLinqToSqlClasses_thumb.jpg\" width=\"479\" border=\"0\"><\/a> <\/li>\n<li>When prompted, click <strong>Yes<\/strong> to add this file to the App_Code folder.&nbsp; This is important b\/c the Web sitfe needs to dynamically compile generated code created by the designer.&nbsp; <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/2B-AddLinqToSqlClasses_2.jpg\"><img decoding=\"async\" height=\"172\" alt=\"2B-AddLinqToSqlClasses\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/12\/2B-AddLinqToSqlClasses_thumb.jpg\" width=\"423\" border=\"0\"><\/a> <\/li>\n<li>Double click NorthwindDataClasses.dbml to open it in the OR Designer. <\/li>\n<\/ol>\n<\/li>\n<li>Add Employee table objects to your Linq to SQL classes\n<ol>\n<li>Open Server Explorer (or Database Explorer in Express) <\/li>\n<li>Expand Northwnd.MDF -&gt; Tables -&gt; Employees <\/li>\n<li>Drag and Drop the <strong>Employees<\/strong> table node from Server Explorer to the NorthwindDataClasses.dbml design surface&nbsp; (NOTE: you could continue to add more Tables, or Stored Procedures, or customize the names\/properties in the designer). <\/li>\n<li><strong>Save All<\/strong> files <\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/3AddingClassesToORDesigner_2.jpg\"><img decoding=\"async\" height=\"304\" alt=\"3AddingClassesToORDesigner\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/12\/3AddingClassesToORDesigner_thumb.jpg\" width=\"430\" border=\"0\"><\/a> <\/p>\n<h5>Laying Out Form UI &amp; DataSource Controls<\/h5>\n<p>Now that we&#8217;ve added the database to the Web site and created necessary LINQ to SQL classes, it&#8217;s time to create some UI and wire up the data to the UI.&nbsp; I won&#8217;t do anything too fancy &#8211; just repeat data bound labels in a DataList (you could replace this with GridView, FormView or choose your favorite control).&nbsp; <\/p>\n<ol>\n<li>Double-click Default.aspx to open the page in the designer <\/li>\n<li>Drag n drop a DataList from the data tab of Toolbox to the Default.aspx design surface (or to the correct DIV area in mark up &#8220;Source&#8221; view) <\/li>\n<li>Drop n drop a LinqDataSource control from the data tab of the Toolbox to the Default.aspx design surface (or just below the DataList in &#8220;Source&#8221; view) <\/li>\n<\/ol>\n<h5>Wiring up the LinqDataSource to Underlying Data (LINQ to SQL &#8211; DataContext)<\/h5>\n<p>The LinqDataSource needs to be wired up to the underlying LINQ data.&nbsp; In this case data is provided by any DataContext object&nbsp; or query over an object of the NorthwindDataClasses type (a LINQ to SQL file).&nbsp; The DataList then simply needs to use the LinqDataSource as the data source, and display data from bound fields using traditional Eval(&#8220;&#8221;) statements.&nbsp; The designer will generate a set of defaults for you if you use the Smart Tags.&nbsp; Let&#8217;s give it a shot with defaults, and then we can fine tune it from there.&nbsp; <\/p>\n<ol>\n<li>Select the LinqDataSource control in the designer.&nbsp; Expand the smart tag and click <strong>Configure Data Source&#8230;<\/strong> <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/4LinqDataSource_2.jpg\"><img decoding=\"async\" height=\"227\" alt=\"4LinqDataSource\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/12\/4LinqDataSource_thumb.jpg\" width=\"429\" border=\"0\"><\/a> <\/li>\n<li>A wizard pops up and should default to picking your <strong>NorthwindDataClasses<\/strong> as the source.&nbsp; (any other queryable sources you add will show up here).&nbsp; Click Next.&nbsp; <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/4bLinqDataSourceWizardDataSource_4.jpg\"><img decoding=\"async\" height=\"319\" alt=\"4bLinqDataSourceWizardDataSource\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/12\/4bLinqDataSourceWizardDataSource_thumb_1.jpg\" width=\"434\" border=\"0\"><\/a> <\/li>\n<li>You can optionally pick any specific subset of columns\/fields.&nbsp; I just chose * for this example.&nbsp; You could even configure a Where clause &#8212; however I honestly think it&#8217;s easier to do parameterized queries and other query operations in code.&nbsp; I&#8217;ll show that later &#8230;&nbsp; Click <strong>Finish<\/strong>.&nbsp; <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2018\/10\/4cLinqDataSourceWizardChooseFields_4.jpg\"><img decoding=\"async\" height=\"317\" alt=\"4cLinqDataSourceWizardChooseFields\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/12\/4cLinqDataSourceWizardChooseFields_thumb_1.jpg\" width=\"431\" border=\"0\"><\/a> <\/li>\n<li>Optionally you can Enable Delete, Insert, and Update for the LinqDataSource using the Smart Tag.&nbsp; <em><strong>TIP<\/strong>: This is handy if you&#8217;re going to build a read\/write web form.&nbsp; <\/em><\/li>\n<\/ol>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/4dLinqDataSourceConfigureCRUD_2.jpg\"><img decoding=\"async\" height=\"220\" alt=\"4dLinqDataSourceConfigureCRUD\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/12\/4dLinqDataSourceConfigureCRUD_thumb.jpg\" width=\"369\" border=\"0\"><\/a> <\/p>\n<p>Here is the resulting mark up for the LinqDataSource as seen in &#8220;Source&#8221; view.&nbsp; Note how the ContextTypeName=&#8221;NorthwindDataClassesDataContext&#8221; &#8212; this matches the name of the type we created in the designer (the code gen appends &#8220;DataContext&#8221; to the end &#8212; whew that&#8217;s long!).&nbsp; The TableName is set to the Table or Property we want to display &#8212; Employees in this case.&nbsp; You could use this pattern to bind to any DataContext type and class property within.&nbsp; <\/p>\n<blockquote>\n<pre class=\"code\"><span>&lt;<\/span><span>asp<\/span><span>:<\/span><span>LinqDataSource <\/span><span>ID<\/span><span>=\"LinqDataSource1\" <\/span><span>runat<\/span><span>=\"server\" <\/span><span>ContextTypeName<\/span><span>=\"<strong>NorthwindDataClassesDataContext<\/strong>\"\n    <\/span><span>TableName<\/span><span>=\"<strong>Employees<\/strong>\"&gt;\n&lt;\/<\/span><span>asp<\/span><span>:<\/span><span>LinqDataSource<\/span><span>&gt;<\/span><\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p><\/blockquote>\n<h5>Binding UI Controls to LinqDataSource<\/h5>\n<p>Now let&#8217;s wire up the DataList to the LinqDataSource.&nbsp; The nice thing here is the DataList only cares about the field names returned from the LINQ query via the LinqDataSource &#8212; this shields you as you continue to refine the fields and row results of your dynamic LINQ queries.&nbsp; <\/p>\n<ol>\n<li>Select the DataList in the designer.&nbsp; Expand the smart tag and Choose Data Source = LinqDataSource1 <\/li>\n<li>Customize the DataList&#8217;s ItemTemplate <\/li>\n<li>Run it!&nbsp; (F5 or View in Browser) <\/li>\n<\/ol>\n<p>The wizard will create a series of bound labels by default.&nbsp; You can use the designer in edit mode to get the specific fields, look and feel you want.&nbsp; <em><strong>TIP:<\/strong> This is typically where I drop in the html mark up &#8220;Source&#8221; view<\/em>.&nbsp; In my example, I&#8217;ll simply show the full name, notes, and have a place holder to show an employee photo image.&nbsp; I also format the data in a two column table.&nbsp; <\/p>\n<p>If you look at the DataList mark up, you see the ItemTemplate contains a number of bound labels.&nbsp; Binding to data from the query is simply a matter of typing in &lt;%# Eval(&#8220;YOURFIELDNAME&#8221;) %&gt; in your server control fields using classic ASP-style &amp; VB data binding eval statements.&nbsp; This gives you a lot of flexibility to display just the data you want, formatted how you want.&nbsp; Here&#8217;s my customization:&nbsp; <\/p>\n<pre class=\"code\"><span>&lt;<\/span><span>div<\/span><span>&gt;\n    &lt;<\/span><span>asp<\/span><span>:<\/span><span>DataList <\/span><span>ID<\/span><span>=\"DataList1\" <\/span><span>runat<\/span><span>=\"server\" <\/span><span>DataKeyField<\/span><span>=\"EmployeeID\" <\/span><span>DataSourceID<\/span><span>=\"LinqDataSource1\"&gt;\n        &lt;<\/span><span>HeaderTemplate<\/span><span>&gt;\n            &lt;<\/span><span>table<\/span><span>&gt;\n        &lt;\/<\/span><span>HeaderTemplate<\/span><span>&gt;\n        &lt;<\/span><span>ItemTemplate<\/span><span>&gt;\n            &lt;<\/span><span>tr<\/span><span>&gt;\n                &lt;<\/span><span>td<\/span><span>&gt;\n                    &lt;<\/span><span>img <\/span><span>src<\/span><span>=\"PLACEHOLDER.jpg\" <\/span><span>class<\/span><span>=\"\" <\/span><span>style<\/span><span>=\"<\/span><span>border<\/span>: <span>4px solid white\" <br \/>                          <\/span><span>alt<\/span><span>='Photo Number XXX' \/&gt;\n                    &lt;<\/span><span>br <\/span><span>\/&gt;&lt;<\/span><span>br <\/span><span>\/&gt;\n                &lt;\/<\/span><span>td<\/span><span>&gt;\n                &lt;<\/span><span>td<\/span><span>&gt;\n                    <\/span>EmployeeID:\n                    <span>&lt;<\/span><span>asp<\/span><span>:<\/span><span>Label <\/span><span>ID<\/span><span>=\"EmployeeIDLabel\" <\/span><span>runat<\/span><span>=\"server\" <\/span><span>Text<\/span><span>='<\/span><span>&lt;%<\/span># Eval(\"EmployeeID\") <span>%&gt;<\/span><span>' \/&gt;\n                    &lt;<\/span><span>br <\/span><span>\/&gt;\n                    &lt;<\/span><span>asp<\/span><span>:<\/span><span>Label <\/span><span>ID<\/span><span>=\"LastNameLabel\" <\/span><span>runat<\/span><span>=\"server\" <br \/>                          <\/span><span>Text<\/span><span>='<\/span><span>&lt;%<\/span># Eval(\"FirstName\") &amp; \" \" &amp; Eval(\"LastName\") <span>%&gt;<\/span><span>' \/&gt;\n                    &lt;<\/span><span>br <\/span><span>\/&gt;\n                    &lt;<\/span><span>asp<\/span><span>:<\/span><span>Label <\/span><span>ID<\/span><span>=\"NotesLabel\" <\/span><span>runat<\/span><span>=\"server\" <\/span><span>Text<\/span><span>='<\/span><span>&lt;%<\/span># Eval(\"Notes\") <span>%&gt;<\/span><span>' \/&gt;\n                &lt;\/<\/span><span>td<\/span><span>&gt;\n            &lt;\/<\/span><span>tr<\/span><span>&gt;\n        &lt;\/<\/span><span>ItemTemplate<\/span><span>&gt;\n        &lt;<\/span><span>FooterTemplate<\/span><span>&gt;\n            &lt;\/<\/span><span>table<\/span><span>&gt;\n        &lt;\/<\/span><span>FooterTemplate<\/span><span>&gt;\n    &lt;\/<\/span><span>asp<\/span><span>:<\/span><span>DataList<\/span><span>&gt;\n&lt;\/<\/span><span>div<\/span><span>&gt;<\/span><\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<blockquote><p>&nbsp;<\/p><\/blockquote>\n<h5>Using Custom LINQ Queries<\/h5>\n<p>The technique above provides a zero-code method for binding Web forms to LINQ data.&nbsp; However, you might be asking yourself, where is the LINQ and VB here?&nbsp; It&#8217;s true the LinqDataSource hides all the querying code and constrains what you can do via the designer.&nbsp; This is fine for some simple cases, but the real power of LINQ is being able to use your own free form queries and VB logic.&nbsp; The good news is LinqDataSource supports using your own LINQ queries using the LinqDataSource.Selecting event.&nbsp; This is your hook to tell the control exactly what query should be used.&nbsp; It&#8217;s easy.&nbsp; Here&#8217;s how:<\/p>\n<ol>\n<li>Right-click on Default.aspx and select View Code &#8230; to see the VB code behind file (Default.aspx.vb).&nbsp; <\/li>\n<li>In the left-hand-side dropdown above the code editor, select the LinqDataSource1 object. <\/li>\n<li>In the right-hand-side dropdown above the code editor, select the Selecting event.&nbsp; The event handler is stubbed out.&nbsp; <\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/5VBDropdownsSelectingEvent_2.jpg\"><img decoding=\"async\" height=\"114\" alt=\"5VBDropdownsSelectingEvent\" src=\"https:\/\/devblogs.microsoft.com\/vbteam\/wp-content\/uploads\/sites\/7\/2007\/12\/5VBDropdownsSelectingEvent_thumb.jpg\" width=\"646\" border=\"0\"><\/a> <\/li>\n<li>Write your custom LINQ query in the event handler.&nbsp; Make sure you set <strong>e.Result = &lt;your LINQ query variable&gt;<\/strong> before the event handler routine is finished running.&nbsp; <\/li>\n<\/ol>\n<p>In my example I will query over Northwind employees, define a custom expression column called FullName (=First + Last), filter by full name starting with A or N, and sort by last name.&nbsp; Note I&#8217;m creating aliases for each property and hence the query is now an anonymous type &#8212; and the schema is now custom&nbsp;vs. my default NorthwindDataContext with all (*) columns.&nbsp; <em><strong>TIP:<\/strong> if you&#8217;re getting runtime errors when you try this make sure all the fields expected by your Web form are there &#8212; e.g. if the form is expecting &#8220;EmployeeID&#8221; make sure your query Selects it.&nbsp; <\/em><\/p>\n<pre class=\"code\"><span>Protected Sub <\/span>LinqDataSource1_Selecting(<span>ByVal <\/span>sender <span>As Object<\/span>, <span>ByVal <\/span>e _\n                                        <span>As <\/span>System.Web.UI.WebControls.LinqDataSourceSelectEventArgs) _\n                                        <strong><span>Handles <\/span>LinqDataSource1.Selecting<\/strong>\n    <span>Dim <\/span>northwind <span>As New <\/span>NorthwindDataClassesDataContext\n    <span>'custom anonymous LINQ query\n    <\/span><span>Dim <\/span>query = <span>From <\/span>emp <span>In <\/span>northwind.Employees _\n                <span>Select <\/span>emp.EmployeeID, emp.FirstName, emp.LastName, emp.Notes, _\n                    <strong>FullName = emp.FirstName &amp; <span>\" \" <\/span>&amp; emp.LastName<\/strong> _\n                <span>Where <\/span>FirstName.ToUpper.StartsWith(<span>\"A\"<\/span>) <span>Or <\/span>FirstName.ToUpper.StartsWith(<span>\"N\"<\/span>) _\n                <span>Order By <\/span>FullName\n    <span>'sets LinqDataSource query equal to custom query.\n    'use data binding expressions to look up aliased fields above.\n    <\/span><strong>e.Result = query<\/strong>\n<span>End Sub<\/span><\/pre>\n<p><a href=\"http:\/\/11011.net\/software\/vspaste\"><\/a><\/p>\n<p>You can run the app again and see the custom query is working &#8212; only two rows are returned &#8212; Andrew Fuller and Nancy Davolio.&nbsp; We could also tweak the markup to make use of our new aliased expression column &#8212; &#8220;FullName&#8221;.&nbsp; Here&#8217;s how that would look in the DataList:<\/p>\n<pre class=\"code\"><span>&lt;<\/span><span>asp<\/span><span>:<\/span><span>DataList <\/span><span>ID<\/span><span>=\"DataList1\" <\/span><span>runat<\/span><span>=\"server\" <\/span><span>DataKeyField<\/span><span>=\"EmployeeID\" <\/span><span>DataSourceID<\/span><span>=\"LinqDataSource1\"&gt;\n    &lt;<\/span><span>HeaderTemplate<\/span><span>&gt;\n        &lt;<\/span><span>table<\/span><span>&gt;\n    &lt;\/<\/span><span>HeaderTemplate<\/span><span>&gt;\n    &lt;<\/span><span>ItemTemplate<\/span><span>&gt;\n        &lt;<\/span><span>tr<\/span><span>&gt;\n            &lt;<\/span><span>td<\/span><span>&gt;\n                &lt;<\/span><span>img <\/span><span>src<\/span><span>=\"PLACEHOLDER.jpg\" <\/span><span>class<\/span><span>=\"\" <\/span><span>style<\/span><span>=\"<\/span><span>border<\/span>: <span>4px solid white\" <\/span><span>alt<\/span><span>='Photo Number XXX' \/&gt;\n                &lt;<\/span><span>br <\/span><span>\/&gt;&lt;<\/span><span>br <\/span><span>\/&gt;\n            &lt;\/<\/span><span>td<\/span><span>&gt;\n            &lt;<\/span><span>td<\/span><span>&gt;\n                <\/span>EmployeeID:\n                <span>&lt;<\/span><span>asp<\/span><span>:<\/span><span>Label <\/span><span>ID<\/span><span>=\"EmployeeIDLabel\" <\/span><span>runat<\/span><span>=\"server\" <\/span><span>Text<\/span><span>='<\/span><span>&lt;%<\/span># Eval(\"EmployeeID\") <span>%&gt;<\/span><span>' \/&gt;\n                &lt;<\/span><span>br <\/span><span>\/&gt;\n                &lt;<\/span><span>asp<\/span><span>:<\/span><span>Label <\/span><span>ID<\/span><span>=\"LastNameLabel\" <\/span><span>runat<\/span><span>=\"server\" <\/span><span>Text<\/span><span>='<\/span><strong><font size=\"4\"><span>&lt;%<\/span># Eval(\"FullName\") <span>%&gt;<\/span><\/font><\/strong><span>' \/&gt;\n                &lt;<\/span><span>br <\/span><span>\/&gt;\n                &lt;<\/span><span>asp<\/span><span>:<\/span><span>Label <\/span><span>ID<\/span><span>=\"NotesLabel\" <\/span><span>runat<\/span><span>=\"server\" <\/span><span>Text<\/span><span>='<\/span><span>&lt;%<\/span># Eval(\"Notes\") <span>%&gt;<\/span><span>' \/&gt;\n            &lt;\/<\/span><span>td<\/span><span>&gt;\n        &lt;\/<\/span><span>tr<\/span><span>&gt;\n    &lt;\/<\/span><span>ItemTemplate<\/span><span>&gt;\n    &lt;<\/span><span>FooterTemplate<\/span><span>&gt;\n        &lt;\/<\/span><span>table<\/span><span>&gt;\n    &lt;\/<\/span><span>FooterTemplate<\/span><span>&gt;\n&lt;\/<\/span><span>asp<\/span><span>:<\/span><span>DataList<\/span><span>&gt;<\/span><\/pre>\n<pre class=\"code\"><span><\/span><\/pre>\n<h5>Summary &amp; More Info<\/h5>\n<p>To wrap things up, it&#8217;s easy to map what you know about Web Forms to what you&#8217;re learning about Linq in VB.&nbsp; The LinqDataSource connects your underlying Linq to SQL DataContext, or any generalized Linq query, to the rest of your Web Form.&nbsp; You can create totally custom queries in the LinqDataSource.Selecting event and pass that to the control via e.Result.&nbsp; And then you can get at any field or property in your Linq query using classic Eval(&#8220;MYFIELD&#8221;) data binding expressions.&nbsp; <\/p>\n<p>What do you think?&nbsp; What additions would you like to see?<\/p>\n<p>If you want more info now, ScottGu put together an <a class=\"\" href=\"http:\/\/weblogs.asp.net\/scottgu\/archive\/2007\/09\/07\/linq-to-sql-part-9-using-a-custom-linq-expression-with-the-lt-asp-linqdatasource-gt-control.aspx\">awesome series of Linq to SQL posts<\/a> for the Web, and he included VB sample code.&nbsp; Another great portal for learning and How To content is <a href=\"http:\/\/www.asp.net\/\">www.asp.net<\/a>.&nbsp; <\/p>\n<p>Best, <\/p>\n<p><font face=\"Papyrus\" size=\"5\"><em>Paul<\/em><\/font><\/p>\n<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>Paul Yuknewicz <br \/>Lead Program Manager <br \/>Microsoft Visual Studio <br \/><a href=\"http:\/\/msdn.com\/vbasic\/\">http:\/\/msdn.com\/vbasic\/<\/a><\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/MSDNBlogsFS\/prod.evol.blogs.msdn.com\/CommunityServer.Components.PostAttachments\/00\/06\/88\/05\/95\/VBWebLINQSample-Complete.zip\">VBWebLINQSample-Complete.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Happy holidays!&nbsp; It&#8217;s been a long time since I&#8217;ve written a post, so I figure I can bring in the new year answering some great questions&nbsp;submitted by&nbsp;you.&nbsp; Just this week someone gave me this feedback: &#8220;I am having a difficult time finding information to help me adapt to LINQ in my webforms. I am hoping [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[21,195],"tags":[94,123,164,166,178],"class_list":["post-4883","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-im-a-vb","category-visual-basic","tag-linqvb9","tag-paul-yuknewicz","tag-vb_express","tag-vb2008","tag-web"],"acf":[],"blog_post_summary":"<p>Happy holidays!&nbsp; It&#8217;s been a long time since I&#8217;ve written a post, so I figure I can bring in the new year answering some great questions&nbsp;submitted by&nbsp;you.&nbsp; Just this week someone gave me this feedback: &#8220;I am having a difficult time finding information to help me adapt to LINQ in my webforms. I am hoping [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/4883","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=4883"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/4883\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=4883"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=4883"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=4883"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}