|
|
These blog entries are written by industry experts and leaders. We consider this content to be a good read for any software developer or web technologist.
Browse by Tags
All Tags » LINQ » Visual Studio (RSS)
-
There has been a lot of excitement in the community about the new ASP.NET MVC framework that is about to ship (literally any day now – announcement coming soon). As with anything new, people are also asking for more tutorials/samples/documentation that cover how to get started and build applications with it. Over the last few months I’ve been helping to contribute to an ASP.NET MVC book that Scott Hanselman, Rob Conery, and Phil Haack have been writing for Wrox. The book is now in production, and will be available to buy in stores soon (you can pre-order it on Amazon today). I wrote the first chapter of the book – which is a 185 page end-to-end tutorial that walks-through building a small, but complete, ASP.NET MVC application from scratch. The agreement I made with Wrox was that I’d write it for free in return for them also making it available as a free PDF download. I’m excited to announce that you can now download this free end-to-end tutorial chapter (it is a 14mb PDF file). It’s licensed under a “Creative Commons Attribution No Derivatives” license – which means you can share, distribute, print, or hand it out to anyone. NerdDinner ASP.NET MVC Tutorial The tutorial starts by using the File->New Project command in Visual Studio to create a brand new ASP.NET MVC project, and then incrementally adds functionality and features. Along the way it covers how to: - Create a database
- Build a model with validation and business rules
- Implement data listing/details UI on a site using Controllers and Views
- Enable CRUD (Create, Update, Delete) data form entry
- Use the ViewModel pattern to pass information from a Controller to a View
- Re-use UI across a site using partials and master pages
- Implement efficient data paging
- Secure an application using authentication and authorization
- Use AJAX to deliver dynamic updates
- Use AJAX to add interactive map support
- Perform automated unit testing (including dependency injection and mocking)
The application the tutorial builds is called “NerdDinner”. It provides an easy way for people to organize, host and search for new topic-based dinners online: Scott Hanselman has been hosting NerdDinners for years, and came up with the idea of building the tutorial around an application that facilitates this. He is also now hosting a live custom-skinned version of the application at www.nerddinner.com) Download Links Hope this helps, Scott P.S. The book is entering production now and so is officially in un-edited status (meaning professional editors haven’t gone through it yet). We’ll update the PDF with any important edits once the text is final. P.P.S. And yes – this is one of the reasons my blog has been more quiet than normal the last few months. Expect more regular blog posting again soon once I recover from this. :-) 
|
-
Apologies for the sparseness of my posting the last few weeks - work and life have been busy here lately. Below is a new post in my link-listing series to help kick things up a little. Also check out my ASP.NET Tips, Tricks and Tutorials page and Silverlight Tutorials page for links to popular articles I've done myself in the past. ASP.NET ASP.NET AJAX .NET -
Ukadc.Diagnostics: Josh Twist pointed me at a new CodePlex project he is working on that extends the System.Diagnostics features in .NET to include richer logging features (SQL trace support, email support, etc). Visual Studio Silverlight WPF Hope this helps, Scott 
|
-
Here is the latest in my link-listing series. Also check out my ASP.NET Tips, Tricks and Tutorials page for links to popular articles I've done myself in the past. ASP.NET ASP.NET AJAX -
Using JQuery with VS 2008 JavaScript Intellisense: One of the improvements we shipped in our recent VS 2008 Hotfix Roll-Up last week was to address issues with JavaScript intellisense support for JQuery (another popular AJAX framework). Brennan Stehling, James Hart, and Lance Fisher have done blog posts recently that discuss how to enable even richer JQuery intellisense inside VS 2008 using intellisense-friendly JQuery libraries that are referenced while coding (and then swapped out for the real library at runtime). You can read their blog posts about how this works here and here and here. Visual Studio -
Visual Studio Programmer Themes Gallery: Visual Studio enables you to customize the color settings of the text editor and IDE, as well as to export and import the settings (use the Tools->Import and Export Settings menu to do this). Scott Hanselman has a great post that provides previews of a bunch of cool pre-built themes that people have published that you can download and use for free. .NET -
Using the Expression Tree Visualizer: Charlie Calvert has a nice post that talks about one of the very useful debugging tools in the LINQ samples package provided with VS 2008. It enables you to easily visualize expression tree variables within the debugger - which can be incredibly useful when you are trying to write your own custom LINQ provider (like the ones above). To learn more about Expression Trees and some of the underlying concepts that make LINQ possible, also check out Charlie's earlier post on them here. Hope this helps, Scott 
|
-
I just arrived back from my trip from Asia, and decided to celebrate (since I'm jet-lagged and can't sleep) with a new post in my link-listing series. You can check out my ASP.NET Tips, Tricks and Tutorials page for links to popular articles I've done myself in the past. ASP.NET ASP.NET AJAX Visual Studio .NET -
Marshaling between Managed and Unmanaged Code: Yi Zhang and Xiaoying Guo from my team in Shanghai have written a great MSDN article that describes how to use the marshaling interop features of the CLR to call native code. One of the tools they highlight is an awesome P/Invoke Interop Assistant application they built that makes it much, much easier to generate p/invoke interop signatures when calling native methods. A must-have tool for anyone doing native/managed interop! IIS -
Microsoft Web Deployment Tool Technical Preview 1: Yesterday the IIS team posted the first preview of a new Microsoft Web Deployment tool. This tool works with both IIS6 and IIS7 and enables automated deployment, synchronization, and migrating of applications on web servers. If you are looking for a great way to automate the deployment of your ASP.NET applications then this tool is definitely one to check out. To learn more, read the walkthroughs at the bottom of this page (in particular the "Introduction to MS Deploy" one). This tool is awesome and should make automated deployment much easier. Hope this helps, Scott 
|
-
LINQ (language integrated query) is one of the new features provided with VS 2008 and .NET 3.5. LINQ makes the concept of querying data a first class programming concept in .NET, and enables you to efficiently express queries in your programming language of choice. One of the benefits of LINQ is that it enables you to write type-safe queries in VB and C#. This means you get compile-time checking of your LINQ queries, and full intellisense and refactoring support over your code: While writing type-safe queries is great for most scenarios, there are cases where you want the flexibility to dynamically construct queries on the fly. For example: you might want to provide business intelligence UI within your application that allows an end-user business analyst to use drop-downs to build and express their own custom queries/views on top of data. Traditionally these types of dynamic query scenarios are often handled by concatenating strings together to construct dynamic SQL queries. Recently a few people have sent me mail asking how to handle these types of scenarios using LINQ. The below post describes how you can use a Dynamic Query Library provided by the LINQ team to dynamically construct LINQ queries. Downloading the LINQ Dynamic Query Library Included on the VS 2008 Samples download page are pointers to VB and C# sample packages that include a cool dynamic query LINQ helper library. Direct pointers to the dynamic query library (and documentation about it) can be found below: Both the VB and C# DynamicQuery samples include a source implementation of a helper library that allows you to express LINQ queries using extension methods that take string arguments instead of type-safe language operators. You can copy/paste either the C# or VB implementations of the DynamicQuery library into your own projects and then use it where appropriate to more dynamically construct LINQ queries based on end-user input. Simple Dynamic Query Library Example You can use the DynamicQuery library against any LINQ data provider (including LINQ to SQL, LINQ to Objects, LINQ to XML, LINQ to Entities, LINQ to SharePoint, LINQ to TerraServer, etc). Instead of using language operators or type-safe lambda extension methods to construct your LINQ queries, the dynamic query library provides you with string based extension methods that you can pass any string expression into. For example, below is a standard type-safe LINQ to SQL VB query that retrieves data from a Northwind database and displays it in a ASP.NET GridView control: Using the LINQ DynamicQuery library I could re-write the above query expression instead like so: Notice how the conditional-where clause and sort-orderby clause now take string expressions instead of code expressions. Because they are late-bound strings I can dynamically construct them. For example: I could provide UI to an end-user business analyst using my application that enables them to construct queries on their own (including arbitrary conditional clauses). Dynamic Query Library Documentation Included with the above VB and C# Dynamic Query samples is some HTML documentation that describes how to use the Dynamic Query Library extension methods in more detail. It is definitely worth looking at if you want to use the helper library in more depth: Download and Run a Dynamic Query Library Sample You can download and run basic VB and C# samples I've put together that demonstrate using the Dynamic LINQ library in an ASP.NET web-site that queries the Northwind sample database using LINQ to SQL: You can use either Visual Web Developer 2008 Express (which is free) or VS 2008 to open and run them. Other Approaches to Constructing Dynamic LINQ Queries Using the dynamic query library is pretty simple and easy to use, and is particularly useful in scenarios where queries are completely dynamic and you want to provide end user UI to help build them. In a future blog post I'll delve further into building dynamic LINQ queries, and discuss other approaches you can use to structure your code using type-safe predicate methods (Joseph and Ben Albahari, authors of the excellent C# 3.0 In a Nutshell book, have a good post on this already here). Hope this helps, Scott 
|
-
Today we shipped Visual Studio 2008 and .NET 3.5. You can download the final release using one of the links below: -
If you are a non-MSDN subscriber, you can download a 90-day free trial edition of Visual Studio 2008 Team Suite here. A 90-day trial edition of Visual Studio 2008 Professional (which will be a slightly smaller download) will be available next week. A 90-day free trial edition of Team Foundation Server can also be downloaded here. -
If you want to use the free Visual Studio 2008 Express editions (which are much smaller and totally free), you can download them here. -
If you want to just install the .NET Framework 3.5 runtime, you can download it here. Quick Tour of Some of the New Features Visual Studio 2008 and .NET 3.5 contain a ton of new functionality and improvements. Below are links to blog posts I've done myself as well as links to videos you can watch to learn more about it: VS 2008 Multi-Targeting Support VS 2008 enables you to build applications that target multiple versions of the .NET Framework. This means you can use VS 2008 to open, edit and build existing .NET 2.0 and ASP.NET 2.0 applications (including ASP.NET 2.0 applications using ASP.NET AJAX 1.0), and continue to deploy these application on .NET 2.0 machines. You can learn more about how this works from my blog post here: ASP.NET AJAX and JavaScript Support .NET 3.5 has ASP.NET AJAX built-in (no separate download required). In addition to including all of the features in ASP.NET AJAX 1.0, ASP.NET 3.5 also now includes richer support for UpdatePanels integrating with WebParts, ASP.NET AJAX integration with controls like <asp:menu> and <asp:treeview>, WCF support for JSON, and many other AJAX improvements. VS 2008 and Visual Web Developer 2008 also now have great support for integrating JavaScript and AJAX into your applications. You can learn more about this from my blog posts here: You can watch some videos that discuss ASP.NET AJAX and Visual Studio 2008 support for it here. I also highly recommend the excellent ASP.NET AJAX in Action book to learn more about ASP.NET AJAX (both client-side and server-side). VS 2008 Web Designer and CSS Support VS 2008 and Visual Web Developer 2008 Express includes a significantly improved HTML web designer (the same one that ships with Expression Web). This delivers support for split-view editing, nested master pages, and great CSS integration. Below are some articles I've written that discuss this more: ASP.NET 3.5 also has a new <asp:ListView> control that provides the ability to perform rich data scenarios with total control over the markup. It works nicely with the new CSS support in VS 2008. You can learn more about it from my article here: You can watch some videos that discuss the new Visual Studio 2008 web designer features and the new ListView/DataPager controls here. Language Improvements and LINQ The new VB and C# compilers in VS 2008 deliver significant improvements to the languages. Both add functional programming concepts that enable you to write cleaner, terser, and more expressive code. These features also enable a new programming model we call LINQ (language integrated query) that makes querying and working with data a first-class programming concept with .NET. Below are some of the articles I've written that explore these new language features using C#: Here are a few additional blog posts I've written that show off some of the new VS 2008 code editing support and some cool ways to use these new language features: The Visual Basic team has also created some great free videos that cover LINQ. You can watch them here. Data Access Improvements with LINQ to SQL LINQ to SQL is a built-in OR/M (object relational mapper) in .NET 3.5. It enables you to model relational databases using a .NET object model. You can then query the database using LINQ, as well as update/insert/delete data from it. LINQ to SQL fully supports transactions, views, and stored procedures. It also provides an easy way to integrate business logic and validation rules into your data model. Below are some of the articles I've written that explore how to use it: I think you'll find that LINQ and LINQ to SQL makes it much easier to build much cleaner data models, and write much cleaner data code. I'll be adding more posts to my LINQ to SQL series in the weeks and months ahead (sorry for the delay in finishing them earlier - so much to-do and so little time to-do it all!). Scott Stanfield is also working on creating some great LINQ to SQL videos for the www.asp.net site based on my article series above (all videos are in both VB and C#). You can watch the first 4 videos in this series here. Browsing the .NET Framework Library Source using Visual Studio As I blogged a few weeks ago, we will be releasing a reference version of the .NET Framework library source code as part of this release. Visual Studio 2008 has built-in debugger support to automatically step-into and debug this code on demand (VS 2008 can pull down the source for the appropriate .NET Framework library file automatically for you). We are deploying the source servers to enable this right now, and will be publishing the steps to turn this feature on in the next few weeks. Lots of other improvements The list above is only a small set of the improvements coming. For client development VS 2008 includes WPF designer and project support. ClickOnce and WPF XBAPs now work with FireFox. WinForms and WPF projects can also now use the ASP.NET Application Services (Membership, Roles, Profile) for roaming user data. Office development is much richer - including support for integrating with the Office 2007 ribbon, and with Outlook. Visual Studio Tools for Office support is also now built-into Visual Studio (you no longer need to buy a separate product). New WCF and Workflow projects and designers are now included in VS 2008. Unit testing support is now much faster and included in VS Professional (and no longer just VSTS). Continuous Integration support is now built-in with TFS. AJAX web testing (unit and load) is now supported in the VS Test SKU. And there is much, much more... Installation Suggestions People often ask me for suggestions on how best to upgrade from previous betas of Visual Studio 2008. In general I'd recommend uninstalling the Beta2 bits explicitly. As part of this you should uninstall Visual Studio 2008 Beta2, .NET Framework Beta2, as well as the Visual Studio Web Authoring Component (these are all separate installs and need to be uninstalled separately). I then usually recommend rebooting the machine after uninstalling just to make sure everything is clean before you kick off the new install. You can then install the final release of VS 2008 and .NET 3.5 on the machine. Once installed, I usually recommend explicitly running the Tools->Import and Export Settings menu option, choosing the "Reset Settings" option, and then re-pick your preferred profile. This helps ensure that older settings from the Beta2 release are no longer around (and sometimes seems to help with performance). Note that VS 2008 runs side-by-side with VS 2005 - so it is totally fine to have both on the same machine (you will not have any problems with them on the same box). Silverlight Tools and VS Web Deployment Project Add-Ins Two popular add-ins to Visual Studio are not yet available to download for the final VS 2008 release. These are the Silverlight 1.1 Tools Alpha for Visual Studio and the Web Deployment Project add-in for Visual Studio. Our hope is to post updates to both of them to work with the final VS 2008 release in the next two weeks. If you are doing Silverlight 1.1 development using VS 2008 Beta2 you'll want to stick with with VS 2008 Beta2 until this updated Silverlight Tools Add-In is available. Hope this helps, Scott 
|
-
Earlier this year I blogged about a new language extensibility feature of C# and VB called "Extension Methods". Extension methods allow developers to add new methods to the public contract of an existing CLR type, without having to sub-class it or recompile the original type. In doing so they enable a variety of useful scenarios (including LINQ). They also provide a really convenient way to add a dash of "syntactic sugar" into your code. Over the last few months I've been making a list of cool extension methods that I plan to sit down and implement when I get some free time (not sure when that is... but at least I can still have fun coming up with the ideas!) Two of the scenarios I added to my extension method list were easy methods to automate generating JSON (JavaScript Object Notation) or XML serialization strings for any .NET object. Simple Scenario: The ToJSON() extension method Assume I had a Person object defined like below (note: I'm using the new automatic properties feature to implement it): I'd like to then be able to initialize a collection of Person objects and programmatically retrieve a JSON string representation of them by just calling a ToJSON() extension method on it like below: This would work just like the built-in ToString() method on the Object class in .NET today - except that it would generate a JSON-format representation of the collection that I could use for AJAX scenarios on the client: Note: Clicking on the hour-glass in the debugger above allows us to bring up the Text Visualizer in VS to see a clean version of the JSON serialization: This string format could then be used within JavaScript on the client to instantiate an appropriate JavaScript object that represents my collection (note: ASP.NET AJAX has a built-in JavaScript library to support this). Implementing the ToJSON Extension Method Implementing a basic ToJSON() extension method is pretty simple. All I needed to-do was use the JavaScriptSerializer class in the System.Web.Script.Serialization namespace, and define two extension methods like below. One of the methods serializes an object graph any levels deep, the other is an overloaded version that allows you to optionally constrain how deep it recurses (for example: ToJSON(2) would serialize only 2 levels deep in the object graph). Note that the ToJSON() extension methods above are defined for type "Object" - which means they can be used with all objects in .NET (not just collections). This means that in addition to calling .ToJSON() on collections like I did above, I could also have called ToJSON() on individual Person objects, as well as any other .NET datatype. To use the extension method, all I need to-do is add a using statement at the top of my program that references the namespace it was defined within: VS 2008 then takes care of providing intellisense and compile time support for it to all objects: Note: In addition to the JavaScriptSerializer class, .NET 3.5 also now includes a new System.Runtime.Serialization.DataContractJsonSerializer class that you can use for JSON serialization/deserialization. Summary Hopefully the above sample provides a simple example of how you can easily encapsulate useful functionality into extension methods. Overtime I expect that we'll start to see some nice utility libraries come out that provide helpful extension methods like above. I'd be curious to see suggestions for other common scenarios you think should be packaged up into re-usable extension methods (feel free to use the comments of this post to suggest them). We can then figure out how to get a good CodePlex project created that bundles up some of them together into one library to easily use. Hope this helps, Scott P.S. Please check out my Tips/Tricks and Tutorials page to find other useful ASP.NET and .NET posts I've done. 
|
-
One of the subtle (but cool) new language features in the VS 2008 version of C# is the ?? "null coalescing" operator. This provides a nice, terse way to check whether a value is null, and if so return an alternate value. Simple Example Usages Several folks have blogged about the ?? operator in the past - read here, here, here, and here for some previous examples on how to use it. Simply put, the ?? operator checks whether the value provided on the left side of the expression is null, and if so it returns an alternate value indicated by the right side of the expression. If the value provided on the left side of the expression isn't null, then it returns the original value. For example, let's assume we have a string variable "message". We could check whether message was null, and return an alternate value using the code below: Because the "message" variable above wasn't null, the "result" variable is assigned the original "hello world" message value. In the code snippet below, however, message is a null value, and so the ?? operator will return the alternate value we've provided: The ?? operator works for both reference types and value types. For example, below we are checking whether the nullable integer "number" variable is null. Because it isn't, the result will be the original value (55): If "number" is null, then result is assigned the value 0: Using the ?? operator with LINQ Last month I wrote a blog post that covered using the new LINQ to XML support in .NET 3.5. One of the "gotchas" you often need to deal with when handling raw XML are cases where XML shapes are irregular and/or missing elements/attributes. The ?? operator can be very useful in these scenarios. For example, let's consider a scenario where we have an XML file or feed with the following contact data: We could write the below LINQ to XML code in C# to open the XML file and retrieve back a sequence of anonymous type objects with "Name", "Title", "Email" and "YearsAtCompany" properties, and then databind the results to an <asp:gridview> control on a page: Notice above how I'm using the explicit conversion operator support on the XElement class to retrieve strongly typed values from the XML. This enables me to just cast the c.Element("YearsAtCompany") value to an int - and it will then automatically convert the string value to an integer for me, and type the "YearsAtCompany" property on my anonymous type to be an int. When we run the above code snippet, we'll then get a nice Gridview listing of our contacts: This explicit conversion support works great when the <YearsAtCompany> element is always defined. But it will throw a runtime error in the case where we have a <Contact> that is missing a <YearsAtCompany> sub-element: One way to fix this is to modify our LINQ to XML query so that we indicate that YearsAtCompany is a nullable integer. We can do this by changing the explicit cast to be (int?) instead of (int): This enables our query to execute cleanly and not raise any errors. Instead a null value will be assigned to the YearsAtCompany property if no <YearsAtCompany> element is present in the XML. When we run the application and databind the results to the Gridview, you can see the YearsAtCompany column for our third contact is empty as a result (since the value is null): But what if we didn't want a missing XML value to result in a null integer value - but instead just indicate a value of 0? Well.... that is where we can use the new ?? operator support. We can just modify the LINQ to XML query like below to indicate a default value of 0 if no element is present: This indicates that if the <YearsAtCompany> element is missing in the XML, and the result would otherwise be null, instead assign a value of 0. Notice in the intellisense above how C# automatically detects that this means that the YearsAtCompany property on the new anonymous type will never be null - and so it marks the property to be of type (int) instead of (int?). And now when we run the page we'll see a value of 0 show up in our third row instead of a blank value: Summary You can use the new C# ?? operator in all types of scenarios. Hopefully the LINQ to XML scenario above provides some interesting food for thought on how you can use it with any LINQ scenario (including LINQ to SQL, LINQ to XML, LINQ to Objects, LINQ to SharePoint, etc). I think you'll find it cool and pretty useful. Hope this helps, Scott 
|
-
Over the last few weeks I've been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL is a built-in O/RM (object relational mapper) that ships in the .NET Framework 3.5 release, and which enables you to model relational databases using .NET classes. You can use LINQ expressions to query the database with them, as well as update/insert/delete data. Below are the first seven parts in this series: In my last two posts (Part 6 and Part 7) I demonstrated how you can optionally use database stored procedures (SPROCs) to query, insert, update and delete data using a LINQ to SQL data model. One of the questions a few people have asked me since doing these posts has been "what if I want total control over the SQL expressions used by LINQ to SQL - but I don't want to use SPROCs to-do it?" Today's blog post will cover that - and discuss how you can use custom SQL expressions that you provide to populate your LINQ to SQL data model classes, as well as perform insert, updates, and deletes. Using LINQ Query Expressions with LINQ to SQL For the purposes of this blog post, let's assume we've used the LINQ to SQL ORM designer in VS 2008 to define a set of data model classes like below for the Northwind database (note: read Part 2 of this series to learn how to use the LINQ to SQL ORM designer to do this):
In Part 3 of this blog series I covered how you can use the new LINQ language support in VB and C# to query the above data model classes and return back a set of objects that represent the rows/columns in the database. For example, we could add a "GetProductsByCategory" helper method to the DataContext class of our data model that uses a LINQ query to return back Product objects from the database: VB:
C#:
Once we've defined our encapsulated LINQ helper method, we can then write code like below that uses it to retrieve the products, and iterate over the results: VB:
When the LINQ expression within our "GetProductsByCategory" method is evaluated, the LINQ to SQL ORM will automatically execute dynamic SQL to retrieve the Product data and populate the Product objects. You can use the LINQ to SQL Debug Visualizer to see in the debugger how this LINQ expression is ultimately evaluated. Using Custom SQL Queries with LINQ to SQL In our sample above we didn't have to write any SQL code to query the database and retrieve back strongly-typed Product objects. Instead, the LINQ to SQL ORM automatically translated the LINQ expression to SQL for us and evaluated it against the database. But what if we wanted total control over the SQL that is run against our database, and don't want LINQ to SQL to-do it for us in this scenario? One way to accomplish this would be to use a SPROC like I discussed in Part 6 and Part 7 of this series. The other approach is to use the "ExecuteQuery" helper method on the DataContext base class and use a custom SQL expression that we provide. Using the ExecuteQuery Method The ExecuteQuery method takes a SQL query expression as an argument, along with a set of parameter values that we can use to optionally substitute values into the query. Using it we can execute any raw SQL we want against the database (including custom JOINs across multiple tables). What makes the ExecuteQuery method really useful is that it allows you to specify how you want the return values of your SQL expression to be typed. You can do this either by passing a type-object as a parameter to the method, or by using a generic-based version of the method. For example, we could change the GetProductsByCategory() helper method we created earlier - using a LINQ expression - to instead use the ExecuteQuery method to execute our own raw SQL expression against the database and return "Product" objects as a result: VB:
C#:
We can then call the GetProductsByCategory() helper method using the exact same code as before:
But unlike before it will be our custom SQL expression that will run against the database - and not dynamic SQL executed in response to using a LINQ query expression. Custom SQL Expressions and Object Tracking for Updates By default when you retrieve a data model object using LINQ to SQL, it will track all changes and updates you make to it. If you call the "SubmitChanges()" method on the DataContext class, it will then transactionally persist all of the updates back to the database. I cover this in more depth in Part 4 of this LINQ to SQL series. One of the cool features of the ExecuteQuery() method is that it can fully participate in this object tracking and update model. For example, we could write the code below to retrieve all products from a specific category and discount their prices by 10%:
Because we typed the return value of our ExecuteQuery call in the GetProductsByCategory method to be of type "Product", LINQ to SQL knows to track the Product objects we returned from it. When we call "SubmitChanges()" on the context object they will be persisted back to the database. Custom SQL Expressions with Custom Classes The ExecuteQuery() method allows you to specify any class as the return type of a SQL query. The class does not have to be created using the LINQ to SQL ORM designer, or implement any custom interface - you can pass in any plain old class to it. For example, I could define a new ProductSummary class that has a subset of Product properties like below (notice the use of the new C# Automatic Properties feature):
We could then create a GetProductSummariesByCategory() helper method on our NorthwindDataContext that returns results based on it. Notice how our SQL statement below requests just the subset of product values we need - the ExecuteQuery method then handles automatically setting these on the ProductSummay objects it returns:
We can then invoke this helper method and iterate over its results using the code below:
Custom SQL Expressions for Inserts/Updates/Deletes In addition to using custom SQL expressions for queries, we can also execute them to perform custom Insert/Update/Delete logic. We can accomplish this by creating the appropriate partial Insert/Update/Delete method for the entity we want to change in a partial class on our DataContext. We can then use the ExecuteCommand method on the DataContext base class to write the SQL we want to execute. For example, to override the Delete behavior for Product classes we could define this DeleteProduct partial method:
And now if we write the below code to remove a specific Product instance from our database, LINQ to SQL will call the DeleteProduct method - which will cause our custom SQL to execute in place of the default dynamic SQL that LINQ to SQL would otherwise use:
Summary The LINQ to SQL ORM automatically generates and executes dynamic SQL to perform queries, updates, inserts and deletes against a database. For advanced scenarios, or cases where you want total control over the SQL query/command executed, you also have the ability to customize the ORM to use either SPROCs, or your own custom SQL Expressions, instead. This provides you with a great deal of flexibility when building and extending your data access layer. In future blog posts in this series I'll cover some remaining LINQ to SQL concepts including: Single Table Inheritance, Deferred/Eager Loading, Optimistic Concurrency, and handling Multi-Tier scenarios. Hope this helps, Scott 
|
-
Over the last few weeks I've been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL is a built-in O/RM (object relational mapper) that ships in the .NET Framework 3.5 release, and which enables you to model relational databases using .NET classes. You can use LINQ expressions to query the database with them, as well as update/insert/delete data. Below are the first six parts in this series: In part 6 I demonstrated how you can optionally use database stored procedures (SPROCs) and user defined functions (UDFs) to query and retrieve data using your LINQ to SQL data model. In today's blog post I'm going to discuss how you can also optionally use SPROCs to update/insert/delete data from the database. To help illustrate this - let's start from scratch and build-up a data access layer for the Northwind sample database: Step 1: Creating our Data Access Layer (without using SPROCs yet) In my Part 2: Defining our Data Model Classes tutorial I discussed how to use the LINQ to SQL ORM designer that is built-in to VS 2008 to create a LINQ to SQL class model like below:
Adding Validation Rules to our Data Model Classes After defining our data model classes and relationships we'll want to add some business logic validation to our data model. We can do this by adding partial classes to our project that add validation rules to our data model classes (I cover how to-do this in-depth in my Part 4: Updating our Database LINQ to SQL tutorial). For example, we could add validation rules to enforce that the Customer's phone number follows a valid phone pattern, and that we don't add Orders where the customer's RequiredDate for delivery is before the actual OrderDate of the Order. Once defined in partial classes like below, these validation methods will automatically be enforced anytime we write code to update our data model objects in an application. VB:
C#:
Adding a GetCustomer() Helper Method to our DataContext Now that we have our data model classes created, and have applied validation rules to them, we can query and interact with the data. We can do this by writing LINQ expressions against our data model classes to query the database and populate them (I cover how to-do this in my Part 3: Querying our Database LINQ to SQL tutorial). Alternatively we could map SPROCs to our DataContext and use them to populate the data model classes (I cover how to-do this in my Part 6: Retrieving Data using Stored Procedures LINQ to SQL tutorial). When building a LINQ to SQL data layer you'll usually want to encapsulate common LINQ queries (or SPROC invocations) into helper methods that you add to your DataContext class. We can do this by adding a partial class to our project. For example, we could add a helper method called "GetCustomer()" that enables us to lookup and retrieve a Customer object from the database based on their CustomerID value: VB:
C#:
Step 2: Using our Data Access Layer (still without SPROCs) We now have a data access layer that encapsulates our data model, integrates business validation rules, and enables us to query, update, insert, and delete the data. Let's look at a simple scenario using it where we retrieve an existing customer object, update the customer's ContactName and Phone Number, and then create a new Order object and associate it with them. We can write the below code to do all of this within a single transaction. LINQ to SQL will ensure that our business logic validation rules are clean before saving anything in the database: VB:
C#:
LINQ to SQL monitors the modifications we make to the objects we retrieve from the DataContext, and keeps track of all of the objects we add into it. When we call DataContext.SubmitChanges() at the end, LINQ to SQL will check that our business logic rules are valid, and if so automatically generate the appropriate dynamic SQL to update our Customer record above, and insert a new record into the Orders table. Hang on a second - I thought this post was about using SPROCs??? If you are still reading this, you might be feeling confused about where SPROCs fit into this post. Why did I show you above how to write code that works with our data model objects, and then causes dynamic SQL to run? Why haven't I showed you how to call a SPROC for doing inserts/updates/deletes instead yet? The reason is that the programming model in LINQ to SQL for working with data model objects backed by SPROCs is the same as those updated via dynamic SQL. The way you add data model validation logic is exactly the same (so all the validation rules on our data model classes above still apply when we use SPROCs). The code snippet above where we use our data access layer to retrieve a customer, update it, and then add a new order associated with it is also exactly the same regardless of whether we are using dynamic SQL for updates, or whether we have configured our data model classes to use SPROCs instead. This programming model symmetry is powerful both in that you don't have to learn two ways of doing things, and also because it means that you don't have to decide up front at the beginning of your project whether you are going to use SPROCs or not. You can start off using the dynamic SQL support provided by the LINQ to SQL ORM for all queries, inserts, updates and deletes. You can then add your business and validation rules to your model. And then later you can optionally update your data mapping model to use SPROCs - or not if you decide you don't want to. The code and tests you write against your data model classes can stay the same regardless of whether you use dynamic SQL or SPROCs. We'll now spend the rest of this blog post demonstrating how we can update the data model we've built to use SPROCs for updates/inserts/deletes - while still using the same validation rules, and working with the same code snippets above. How to Use SPROCs for Insert/Update/Delete Scenarios We can modify the data access layer we've been building to use SPROCs to handle updates, instead of dynamic SQL, in one of two ways: 1) By using the LINQ to SQL designer to graphically configure SPROCs to execute in response to Insert/Update/Delete operations on our data model classes. or: 2) By adding a NorthwindDataContext partial class in our project, and then by implementing the appropriate Insert/Update/Delete partial methods provided on it (for example: InsertOrder, UpdateOrder, DeleteOrder) that will be called when we insert/update/delete data model objects. These partial methods will be passed the data model instances we want to update, and we can then execute whatever SPROC or SQL code we want to save it within the database. When we use approach #1 (the LINQ to SQL designer) to graphically configure SPROCs to call, it is under the covers generating the same code (in a partial class it creates) that you'd write when using approach #2. In general I'd recommend using the LINQ to SQL designer to configure the SPROCs for the 90% case - and then in more advanced scenarios go in and custom tweak the SPROC invocation code it generates if you need to. Step 3: Doing Order Inserts with a SPROC We'll begin switching our data model to use SPROCs by starting with the Order object. We'll first go to the Visual Studio "Server Explorer" window, expand into the "Stored Procedures" node of our database, and then right-click and choose "Add New Stored Procedure": We'll then create a new SPROC that we'll call "InsertOrder" that inserts a new order record into our Orders table: Notice above how the SPROC defines the "OrderID" parameter as an output param. This is because the OrderID column in the database is an identity column that is set to auto-increment each time a new record is added. The caller of the SPROC will pass in NULL as a value when calling it - and the SPROC then passes back the newly created OrderID value as the output value (by calling the SCOPE_IDENTITY() function at the end of the SPROC). After creating the SPROC we'll then open up the LINQ to SQL ORM designer for our data access layer. Like I discussed in my last blog post in this series (Part 6: Retrieving Data Using Stored Procedures), we can drag/drop SPROCs from the server-explorer onto the method pane of our DataContext designer. We'll want to-do this with our newly created InsertOrder SPROC: Our last step will be to tell our data access layer to use the InsertOrder SPROC when inserting new Order objects into the database. We can do that by selecting the "Order" class in the LINQ to SQL ORM designer, and then by going to the property grid and clicking the "..." button to override how Insert operations happen for it: Clicking the "..." button will bring up a dialog that allows us to customize how insert operations happen: Notice above how the default mode ("Use Runtime") is to have LINQ to SQL calculate and execute dynamic SQL to handle the insert operations. We can change that by selecting the "Customize" radio button and then pick our InsertOrder SPROC from the list of available SPROCs: The LINQ to SQL designer will populate a parameter list for the SPROC we picked, and enable us to map properties on our Order class to parameters of our InsertOrder SPROC. By default it is smart and tries to "best match" them based on name. You can go in and override them if you want. Once we click "ok" on the dialog, we are done. Now whenever a new Order is added to our DataContext and the SubmitChanges() method is invoked, our InsertOrder SPROC will be used instead of executing dynamic SQL. Important: Even though we are now using a SPROC for persistence, the custom Order "OnValidate()" partial method we created earlier (in step 1 of this blog post) to encapsulate Order validation rules still executes before any changes are saved or the SPROC is invoked. This means we have a clean way to encapsulate business and validation rules in our data models, and can re-use them regardless of whether dynamic SQL or SPROCs are used. Step 4: Doing Customer Updates with a SPROC Now let's modify our Customer object to handle updates using a SPROC. We'll start by creating a new "UpdateCustomer" SPROC like below: Notice above how in addition to passing in the @CustomerID parameter, we are also passing in a @Original_CustomerID parameter. The CustomerID column in the Customers table is not an auto-increment identity column, and it can be modified as part of an update of the Customer object. Consequently we need to be able to provide the SPROC with both the original CustomerID and the new CustomerID in order to update the record. We'll look at how we map this using the LINQ to SQL designer shortly. You'll notice above how I'm also passing in a @Version parameter (which is a timestamp) to the SPROC. This is a new column I've added to the Northwind Customers table to help handle optimistic concurrency. I will cover optimistic concurrency in much more depth in a later blog post in this LINQ to SQL series - but the short summary is that LINQ to SQL fully supports optimistic concurrency, and enables you to use either a version timestamp or to supply both original/new values to your SPROCs to detect if changes have been made by another user since you last refreshed your data objects. For this sample I'm using a timestamp since it makes the code much cleaner. Once we've created our SPROC, we can drag/drop it onto the LINQ to SQL designer to add it as a method on our DataContext. We can then select the Customer class in the ORM designer and click the "..." button to override the Customer object's Update behavior in the property grid: We'll select the "Customize" radio button and pick our UpdateCustomer SPROC to use: When mapping our Customer object's properties to the SPROC parameters, you'll notice that we'll want to be deliberate about whether we supply the "current" property value on the data object, or the original value that was in the database when the object was first retrieved. For example, we'll want to make sure we map the "current" value of the Customer.CustomerID property for the @CustomerID SPROC parameter, and that we map the original value for the @original_customerID SPROC parameter. Once we click "ok" on the dialog, we are done. Now whenever a new Customer is updated and the SubmitChanges() method is invoked, our UpdateCustomer SPROC will be used instead of executing dynamic SQL. Important: Even though we are now using a SPROC for persistence, the Customer "OnPhoneChanging()" partial method we created earlier (in step 1 of this blog post) to encapsulate Phone Number validation rules still executes before any changes are saved or the SPROC is invoked. We have a clean way to encapsulate business and validation rules in our data models, and can re-use them regardless of whether dynamic SQL or SPROCs are used. Step 5: Using our Data Access Layer Again (this time with SPROCs) Once we've updated our data layer to use SPROCs instead of dynamic SQL for persistence, we can re-run the exact same code we wrote in Step 2 earlier against our data model classes: Now the updates for the Customer object, and the insert for the Order object, are executing via SPROCs instead of dynamic SQL. The validation logic we defined still executes just like before, though, and the data access code we write to use the data model classes is exactly the same. Some Advanced Notes When Using SPROCs A few quick notes that you might find useful for more advanced SPROC scenarios with LINQ to SQL: Usage of SPROC Output Params: In the Insert scenario (Step 3) above I showed how we could return back the new OrderID value (which is an auto-increment identity column in the Orders table) using an output parameter of the SPROC. You aren't limited to only returning back identity column values when using SPROCs with LINQ to SQL - in fact you can update and return back output values for any parameter of your SPROC. You can use this approach both for Insert and Update scenarios. LINQ to SQL will then take the return value and use it to update the property value of your data model object without you having to-do any second queries against the database to refresh/populate them. What Happens if the SPROC Throws an Error? If a SPROC raises an error when doing an Insert/Update/Delete operation, LINQ to SQL will automatically cancel and rollback the transaction of all changes associated with the current SubmitChanges() call on the DataContext. This ensures that your data is always kept in a clean, consistent state. Can you write code instead of using the ORM designer to call SPROCs? As I mentioned earlier in this post, you can use either the LINQ to SQL ORM designer to map your insert/update/delete operations to SPROCs, or you can add partial methods on your DataContext class and programmatically invoke them yourself. Here is an example of the explicit code you could write in a partial class for the NorthwindDataContext to override the UpdateCustomer behavior to call a SPROC: The code above was actually what was generated by the LINQ to SQL ORM designer when we used the designer to map the SPROC and then associate the update behavior of the Customer object with it. You can use it as a starting point and then add any additional logic you want to it to make it more advanced (for example: use the return value of the SPROC to raise custom exceptions for error conditions, optimistic concurrency, etc). Summary LINQ to SQL is a very flexible ORM. It enables you to write clean object-oriented code to retrieve, update and insert data. Best of all - it enables you to cleanly design data model classes independent of how they are persisted and loaded from a database. You can use the built-in ORM engine to efficiently retrieve and update data in the database using dynamic SQL. Or alternatively you can configure your data layer to use SPROCs. The nice thing is that your code consuming the data layer, and all of the business logic validation rules you annotate it with, can be the same regardless of which persistence approach you use. In future blog posts in this series I'll cover some remaining LINQ to SQL concepts including: Single Table Inheritance, Deferred/Eager Loading, Optimistic Concurrency, and handling Multi-Tier scenarios. I'm on vacation next week, and so will hopefully have some free time to get a few of them written then. Hope this helps, Scott 
|
-
One of the new controls in ASP.NET 3.5 that I think will be very popular is the <asp:ListView> control. The ListView control supports the data editing, insertion, deleting, paging and sorting semantics of higher-level controls like the GridView. But - unlike the GridView - it provides you with complete control over the html markup generated. The ListView control, when combined with the new Web Designer and rich CSS support in VS 2008, enables you to build much cleaner HTML UI. Over the next few weeks I'll be putting together several blog posts that show off how you can use it. Building a Products Catalog Page For today's blog post we are going to start simple and just build a basic product catalog listing page like below: This products.aspx page will take a Catalog index in the URL, and use LINQ to SQL to retrieve and display product information. We will also enable paging navigation at the bottom of the product listing (and do all of the paging operations in the database - so that only 6 products at a time are retrieved from the database). The HTML markup output from the server will be 100% CSS based (no tables or inline styles). Step 1: Defining out Site Layout with Nested Master Pages Before we start working on our product page, we'll first want to define the overall UI and layout structure for our site. If you are "design challenged" like me, one approach you might want to take with a new site is to get started by using one of the free HTML site templates that you can download from these two sites: http://www.opensourcetemplates.org/ or http://www.oswd.org/. The templates on these sites are pure HTML (meaning you can use them with any server-side programming technology), and are built using clean CSS and XHTML markup. For this blog post I decided to go with the "TerraFirma" template here. After I downloaded the template, the first thing I did was to create a root "Site.Master" Master Page that defined the overall layout structure for the site. I then created a few nested master pages to define different column style layouts ("SingleColumn.master" and "TwoColumn.master"). VS 2008 now has great support for creating and using nested master pages that makes doing this easy. You can read about how to define and use them in my earlier VS 2008 Nested Master Page Support blog post. Once we have created our master pages layouts, we can then create a new product catalog page for the site that is based on the single-column nested master page (click below for a full screen picture): Notice above how we can edit the page using the new VS 2008 Split View mode feature. Above I'm using the "Vertical Split View" option so that I can see both the source and design view on a wide-screen monitor. You can learn how to enable this in my earlier Enabling Vertical Split View in VS 2008 blog post. Step 2: Defining our CSS Rules using Mock HTML UI When it comes to defining our product UI for the page, there are a couple of different approaches we can use. One would be to start by writing code to generate some dynamic data UI, and then work to make it pretty. Another approach we could take would be to start by mocking up the HTML UI first, and then once we are happy with it write the code to make it dynamic. For this blog post I'm going to take this second approach. To start let's just add a standard <ul><li> list of product content into the page: As you can see above, this <ul> list looks pretty unattractive, and obviously not like what we want our product listing page to look like. To make it more attractive, we'll use some of the new CSS editing features I covered in my earlier VS 2008 Web Designer and CSS Support blog post. Specifically we'll want to open the new "Manage Styles" tool window in VS 2008 (you can open this by selecting the Format->CSS Styles->Managed Styles menu item): The manage styles window provides an easy way for us to see all CSS rules currently in our CSS stylesheet. It also enables us to quickly lookup CSS selector values, refactor css rules across stylesheets, and create new rules. We can create a new CSS rule for our product listing by selecting the "New Style..." link in the "Manage Styles" window. This will bring up a dialog that enables us to choose where we want to define the CSS rule, and configure what settings we want for it. For this sample we'll name the CSS selector ".productslist li" and select the "Define in existing style sheet" option to add it to the external stylesheet we already have for our application: We can then hit "ok", and return back to source mode to assign the CSS rule on our <ul> list (note how VS 2008 now provides CSS intellisense in source view): Currently our CSS rule doesn't have settings assigned to it, so our <ul> list will still look the same as it did before. We can change that by assigning some CSS settings. There are a couple of ways we could set these CSS settings: 1) open up the CSS stylesheet and set them in source mode, 2) use the manage styles dialog we saw before to set them, or 3) use the new CSS Properties Window to edit the CSS rules in real-time within the designer. We can bring up the CSS Properties Windows via the View->CSS Properties menu: When you select an element either in source-view or design-view, the CSS Properties Windows will list all of the CSS rules that apply to it. The "Applied Rules" list at the top of the CSS Properties window indicates the precedence order of cascading rules. The CSS properties list below it then shows all of the setting values assigned to that element. The "target rule" drop down in the style application toolbar (circled in red above) indicates which CSS selector a change in the CSS Properties window will be assigned to. In the example above our .productlist li rule is the CSS selector we currently have selected - which means as we set values in the CSS Properties window they will be persisted under that rule name in our external CSS stylesheet. No style settings will be persisted inline the HTML page. Let's now make some changes to our "productlist li" CSS rule. First we'll change the layout display mode to be "inline": We'll then want to float each <li> to the left: And lastly we'll set the bottom and left margin of each <li> element to be 15px to space out the products nicely: Notice how when we are done no inline styles have been saved in our HTML page: Instead they've all been cleanly saved under our "productlist li" CSS selector in the external CSS stylesheet: Now all that remains is for us to replace the static HTML with some dynamic data coming from a database. Step 3: Defining our LINQ to SQL Data Model We'll use LINQ to SQL to retrieve our product data from the database. LINQ to SQL is a great new ORM (object relational mapper) implementation built into .NET 3.5. You can learn more about it from my on-going LINQ to SQL blog series (more posts in it coming soon): We'll use the Northwind sample database for our product data, and define our data model classes in the LINQ to SQL ORM designer like so: Once we have our LINQ to SQL data model defined, we are ready to use the <asp:listview> control and bind the data to it. Step 4: Convert our HTML Mock UI to use the <asp:ListView> control The <asp:listview> control is a template-driven control. The control itself outputs no "built-in" UI, nor any actual HTML markup. Instead, you can define whatever markup *you* want displayed using the below templates: - LayoutTemplate
- ItemTemplate
- AlternatingItemTemplate
- SelectedItemTemplate
- EditItemTemplate
- InsertItemTemplate
- EmptyItemTemplate
- EmptyDataTemplate
- ItemSeparatorTemplate
- GroupTemplate
- GroupSeparatorTemplate
The first two templates in the list above - LayoutTemplate and ItemTemplate - are the most common ones you'll end up using. The <LayoutTemplate> template allows you to define the outer container/wrapper of your data UI. The <ItemTemplate> template then allows you to define what each item in the list should look like. Within the <LayoutTemplate> you then define an "ItemContainer" control that indicates where you want the <asp:ListView> control to dynamically add the <ItemTemplate> items into the output markup. To see how this works in action, we could take our mock products HTML UI: And replace it with a <asp:listview> that can dynamically generate the exact same markup output like so: Notice above how I am using a <asp:placeholder> control in the <LayoutTemplate> to indicate where I want to add in my items in the list. I could use other controls instead as the itemContainer if I wanted to - but by using an <asp:placeholder> control as the itemContainer I will prevent any id values or extra markup being generated. Notice above how I've also defined an <EmptyDataTemplate>. This will display instead of the <LayoutTemplate> if I assign an empty sequence of data to the ListView. This will avoid us inadvertently displaying an empty <ul></ul> element in the event that there are no products in the catalog specified. Once we've defined our template above, we can write some code in our code-behind file to retrieve our product data using LINQ to SQL, and bind our ListView with it: VB: C#: And now when we run the page and supply a valid categoryid as a querystring argument we'll see our products dynamically pulled from the database: If we try a category that doesn't contain products, we'll get our empty template message: If you do a "view source" on the products page in the browser, you'll see that the markup generated from our ListView control is the same as what our static HTML was: There are no ID elements or inline styles generated. We had complete control over every HTML element and attribute generated. Step 5: Using a <asp:LinqDataSource> control instead of writing code In our previous step above we wrote procedural LINQ to SQL code to databind our <asp:ListView>. This obviously works, and provides a great deal of control over the logic executed. Another option you can alternatively use is a declarative ASP.NET datasource control. All of the ASP.NET 2.0 datasource controls (SqlDataSource, ObjectDataSource, AccessDataSource, XmlDataSource, SiteMapDataSource, etc) work with the ListView. You can also use the new <asp:LinqDataSource> control with it. For more information on the LinqDataSource, check out my previous LINQ to SQL Part 5: Binding UI using the ASP:LinqDataSource Control blog post. To use the <asp:LinqDataSource> in the above sample, we'll first delete the previous code we wrote in the code-behind file, and then click on the <asp:ListView> control in the designer and select the "Choose Data Source->New DataSource" option. We'll pick the "LINQ DataSource" option in the data source dialog, and then bind to the Northwind data model we created earlier. We can then choose to bind the ListView against the "Products" entity collection in our Northwind data model: We can then hit the "Where" button to configure a LINQ filter based on the "category" value in the querystring (we could alternatively bind the value from a form value, cookie, session value, another control, etc): When we press the "ok" button the ListView's DataSourceID will be set to a new <asp:LinqDataSource> in the page: And now without us having to have any code in the application we have a product listing with custom HTML UI databinding against our LINQ to SQL data model. Step 6: Enabling Server Side Paging using the <asp:DataPager> control Our last step with this sample will be to enable paging support over the products data. Specifically, we only want to display 6 products at a time on the page, and provide a nice page number UI to allow users to navigate forward and backwards over our product sequence. One of the other new controls in ASP.NET 3.5 is the <asp:DataPager> control - which makes data paging scenarios with the ListView control pretty easy. You can drop it anywhere you want on a page, and set its "PagedControlID" property to point at the ListView, and its "PageSize" property to indicate how many items in the ListView you want displayed at a time: The <asp:DataPager> will then output navigation UI for your ListView: And then if you click the "2" link in the paging UI above it will show you the remaining 5 products in the category: The <asp:LinqDataSource> automatically uses LINQ to SQL's built-in support for server-side data paging to ensure that only 6 products (because the PageSize is 6) are ever retrieved from the database at a time. This means that your application and database will scale even if you have thousands of products in a specific category. Disclaimer: The <asp:DataPager> in Beta2, though, does have some limitations in that it can't by default be driven off of a querystring value - which makes it not very SEO friendly. I'll cover how to fix this and support a querystring index in a future blog post. Summary Hopefully the above walkthrough provides a good first look overview of how to use the new <asp:ListView> control. You will find that this control provides you with complete control over the markup output sent down to a client - while still providing rich data paging, editing, deleting and insertion semantics. I'll cover many more of these scenarios (along with the ListView's cool grouping functionality) in future blog posts. Click here to download a copy of the above sample in order to try it out on your own machine. Hope this helps - and have a great weekend! Scott 
|
-
One of the big programming model improvements being made in .NET 3.5 is the work being done to make querying data a first class programming concept. We call this overall querying programming model "LINQ", which stands for .NET Language Integrated Query. LINQ supports a rich extensibility model that facilitates the creation of efficient domain-specific providers for data sources. .NET 3.5 ships with built-in libraries that enable LINQ support against Objects, XML, and Databases. What is LINQ to XML? LINQ to XML is a built-in LINQ data provider that is implemented within the "System.Xml.Linq" namespace in .NET 3.5. LINQ to XML provides a clean programming model that enables you to read, construct and write XML data. You can use LINQ to XML to perform LINQ queries over XML that you retrieve from the file-system, from a remote HTTP URL or web-service, or from any in-memory XML content. LINQ to XML provides much richer (and easier) querying and data shaping support than the low-level XmlReader/XmlWriter API in .NET today. It also ends up being much more efficient (and uses much less memory) than the DOM API that XmlDocument provides. Using LINQ to XML to query a local XML File To get a sense of how LINQ to XML works, we can create a simple XML file on our local file-system like below that uses a custom schema we've defined to store RSS feeds: I could then use the new XDocument class within the System.Xml.Linq namespace to open and query the XML document above. Specifically, I want to filter the <Feed> elements in the XML file and return a sequence of the non-disabled RSS feeds (where a disabled feed is a <Feed> element with a "status" attribute whose value is "disabled"). I could accomplish this by writing the code below: VB: C#: Notice in the code-snippets above how I'm loading the XML file using the XDocument.Load(path) static method - which returns back an XDocument object. Because I'm running this code within ASP.NET, I'm using the Server.MapPath(path) helper method to resolve the correct path for my XML file relative to the page I'm running the code on. Once I have an XDocument object for my XML file I can then write a LINQ query expression to retrieve the XML data I'm looking for. In the code above I'm querying over each of the <Feed> elements within the XML file. This is driven by this opening clause in the LINQ query expression: from feed in feedXML.Decedents("Feed") I'm then applying a filter that only returns back those "Feed" elements that either don't have a "status" attribute, or whose "status" attribute value is not set to "disabled": Where (feed.Attribute("status") Is Nothing) OrElse (feed.Attribute("status").Value <> "disabled") I am then using the select clause in our LINQ expression to indicate what data I want returned. If I simply wrote "select feed", LINQ to XML would return back a sequence of XElement objects that represents each of the XML element nodes that match my filter. In the code samples above, though, I am using the shaping/projection features of LINQ to instead define a new anonymous type on the fly, and I am defining two properties on it - Name and Feed - that I want populated using the <Name> and <Url> sub-elements under each <Feed> element: Select Name = feed.Element("Name").Value, Url = feed.Element("Url").Value As you can see above (and below), I can then work against this returned sequence of data just like I would any collection or array in .NET. VS 2008 provides full intellisense and compilation checking support over this anonymous type sequence: I can also data-bind the results against any UI control in ASP.NET, Windows Forms, or WPF. For example, assuming I had a dropdownlist control defined in my page like so: I could use the below LINQ to XML code to databind the results to it: This will then produce a nice drop-downlist in our HTML page like so: Hmm - What is this "anonymous type" thing? In my code above I've taken advantage of a new language feature in VB and C# called "anonymous types". Anonymous types enable developers to concisely define inline CLR types within code, without having to explictly define a formal class declaration of the type. You can learn more about them in my previous New "Orcas" Language Feature: Anonymous Types blog post. While anonymous types can be super useful when you want to locally iterate and work with data, we'll often want/need to define a standard class when passing the results of our LINQ query between multiple classes, across class library assemblies, and over web-services. To enable this, I could define a non-anonymous class called "FeedDefinition" to represent our Feed data like so: Note above how I'm using the new "Automatic Properties" feature of C# to define the properties (and avoid having to define a field for them). I could then write the below method to return back a generics based List<FeedDefinition> collection containing FeedDefinition objects: Note above how the only change I've made to the LINQ to XML query we were using before is to change the "select" clause from "select new" (with no type-name) to "select new FeedDefinition". With this change I'm now returning a sequence of FeedDefinition objects that I can pass from class to class, assembly to assembly, and across web-services. Using LINQ to XML to Retrieve a Remote RSS XML Feed The XDocument.Load(path) static method supports the ability open both XML files from the file-system, as well as remote XML feeds returned from an HTTP URL. This enables you to use it to access remote RSS feeds, REST APIs, as well as any other XML feed published on the web. For an example of this in action, let's take a look at the XML of my blog's RSS feed (http://weblogs.asp.net/scottgu/rss.aspx): I could write the LINQ to XML code below to retrieve the above blog post data from my RSS feed, and work with the individual feed items as .NET objects: Note above how I am converting the "Published" field in the RSS field - which is a string in the XML - to a .NET DateTime object. Notice also how LINQ to XML includes a built-in XNamespace type that provides a type-safe way to declare and work with XML Namespaces (which I need to-do to retrieve the <slash:comments> element). I could then take advantage of the composition features of LINQ to perform a further sub-query on the result, so that I filter over only those RSS posts that were published within the last 7 days using the code below: As you can see above, you can feed the results of one LINQ query expression to be the input of another LINQ expression. This enables you to write very clean, highly composable, code. Using LINQ Sub-Queries within a LINQ to XML Query Expression If you look at the raw XML of my RSS feed, you'll notice that the "tag" comments for each post are stored as repeated <category> elements directly below each <item> element: When designing the object model for a "BlogEntry" class, I might want to represent these <category> values as a sub-collection of strings. For example, using a "Tags" property that is a generic list of type string: You might be wondering - how do we take a flat collection of <category> elements under <item> and transform them into a nested sub-collection of strings? The nice thing about LINQ is that it makes this type of scenario easy by allowing us to use nested LINQ query expressions like so: This "shaping" power of LINQ, and its ability to take flat data structures and make them hierarchical (and take hierarchical data structures and make them flat) is super powerful. You can use this feature with any type of data source - regardless of whether it is XML, SQL, or plain old objects/arrays/collections. Putting it all Together with a Simple RSS Feed Reader The code snippets I've walked through above demonstrate how you can easily write LINQ to XML code to retrieve a list of RSS feeds from a local XML file, and how to remotely query an RSS feed to retrieve an individual feed's details and individual item post contents. I could obviously then take the resulting feed contents and data-bind it to a ASP.NET GridView or ListView control to provide a nice view of the blog feed: I've built a simple sample application that puts all of these snippets together to deliver a simple RSS Reader with LINQ to XML and the new <asp:ListView> control. You can download it here. Included in the download is both a VB and C# version of the application. Summary LINQ to XML provides a really powerful way to efficiently query, filter, and shape/transform XML data. You can use it both against local XML content, as well as remote XML feeds. You can use it to easily transform XML data into .NET objects and collections that you can further manipulate and transfer across your application. LINQ to XML uses the same core LINQ query syntax and concepts that LINQ to SQL, LINQ to Objects, LINQ to SharePoint, LINQ to Amazon, LINQ to NHibernate, etc. use when querying data. You can learn more about the LINQ query syntax and the supporting language features being added to VB and C# to support it from these previous blog posts of mine: You might also find these blog posts of mine useful to learn more about LINQ to SQL: In a future blog post I'll return to LINQ to XML and demonstrate how it can be used not just to query XML, but also to really cleanly generate XML output from a .NET data structure. Hope this helps, Scott 
|
-
Probably the biggest programming model improvement being made in .NET 3.5 is the work being done to make querying data a first class programming concept. We call this overall querying programming model "LINQ", which stands for .NET Language Integrated Query. Developers can use LINQ with any data source, and built-in libraries are included with .NET 3.5 that enable LINQ support against Objects, XML, and Databases. Earlier this summer I started writing a multi-part blog series that discusses the built-in LINQ to SQL provider in .NET 3.5. LINQ to SQL is an ORM (object relational mapping) implementation that 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 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. You can learn more about LINQ to SQL by reading my posts below (more will be coming soon): Using the LINQ to SQL Debug Visualizer One of the nice development features that LINQ to SQL supports is the ability to use a "debug visualizer" to hover over a LINQ expression while in the VS 2008 debugger and inspect the raw SQL that the ORM will ultimately execute at runtime when evaluating the LINQ query expression. For example, assume we write the below LINQ query expression code against a set of data model classes: We could then use the VS 2008 debugger to hover over the "products" variable after the query expression has been assigned: And if we click the small magnifying glass in the expression above, we can launch the LINQ to SQL debug visualizer to inspect the raw SQL that the ORM will execute based on that LINQ query: If you click the "Execute" button, you can even test out the SQL query and see the raw returned results that will be returned from the database: This obviously makes it super easy to see precisely what SQL query logic LINQ to SQL ORM is doing for you. You can learn even more about how all this works by reading the Part 3: Querying our Database segment in my LINQ to SQL series above. How to Install the LINQ to SQL Debug Visualizer The LINQ to SQL Debug Visualizer isn't built-in to VS 2008 - instead it is an add-in that you need to download to use. You can download a copy of it here. The download contains both a binary .dll assembly version of the visualizer (within the \bin\debug directory below), as well as all of the source code for the visualizer: To install the LINQ to SQL debug visualizer, follow the below steps: 1) Shutdown all running versions of Visual Studio 2008 2) Copy the SqlServerQueryVisualizer.dll assembly from the \bin\debug\ directory in the .zip download above into your local \Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers\ directory: 3) Start up Visual Studio 2008 again. Now when you use the debugger with LINQ to SQL you should be able to hover over LINQ query expressions and inspect their raw SQL (no extra registration is required). Hope this helps, Scott 
|
-
I've blogged in the past about some of the text editor improvements in VS 2008 that have been made for JavaScript intellisense and CSS style intellisense. Recently I was looking over the shoulder of someone writing some code, and saw them using some other new text editing features that I hadn't seen before ("wait - how did you just do that?"). Below is a non-exhaustive list of a few new code editing improvements I've learned about this week. I'm know there are many more I don't know about yet - but I thought these few were worth sharing now: Transparent Intellisense Mode One of the things I sometimes find annoying with intellisense in VS 2005 is that the intellisense drop-down obscures the code that is behind it when it pops-up: With VS 2005 I often find myself needing to escape out of intellisense in order to better see the code around where I'm working, and then go back and complete what I was doing. This sometimes ends up disturbing my train of thought and typing workflow. VS 2008 provides a nice new feature that allows you to quickly make the intellisense drop-down list semi-transparent. Just hold down the "Ctrl" key while the intellisense drop-down is visible and you'll be able to switch it into a semi-transparent mode that enables you to quickly look at the code underneath without having to escape out of intellisense: When you release the "Ctrl" key, the editor will switch back to the normal intellisense view and you can continue typing where you were in the Intellisense window. This feature works with all language (VB, C#, and JavaScript). It also works with HTML, XAML and XML based markup. VB Intellisense Filtering The VB team has made some nice improvements to intellisense that make it much easier to navigate through APIs. Intellisense completion now automatically filters the member list available as you type to help you better pinpoint the API you are looking for. For example, if in an ASP.NET code-behind page you type "R" it will show the full list of types and members available (with the selection starting in the "R" list): When you type the second character of what you are looking for (in this case "e"), VB will automatically filter to only show those types that start with "Re" and highlight the most likely option: When you type the "s" it filters the list even further: When you type "p" it filters down to just the one option available: I find this cleaner and more intuitive than the previous model that always showed everything in the drop-down. VB LINQ Intellisense I've done several posts in the past about LINQ and LINQ to SQL. Both VB and C# obviously have full support for LINQ and LINQ to SQL. I think the VB team in particular has done some nice work to provide nice intellisense hints to help guide users when writing LINQ statements in the editor. For example, assuming we have a LINQ to SQL data model like the one I built in Part 2 of my LINQ to SQL series, I could use the VB code editor to easily work with it. Notice below how VB automatically provides a tooltip that helps guide me through writing the LINQ query syntax: I can then start writing my query expression and the VB intellisense will guide me through creating it: The above expression retrieves three column values from the database and creates a new anonymous type that I can then loop over to retrieve and work on the data: Organize C# Using Statements The C# editor has added some great intellisense improvements as well. Some of the biggest obviously include language intellisense and refactoring support for the new language features (Lambdas, Extension Methods, Query Syntax, Anonymous Types, etc). Just like in our VB example above, C# supports type inference and intellisense completion of anonymous types: One of the small, but nice, new features I recently noticed in VS 2008 is support for better organizing using statements in C#. You can now select a list of using statements, right-click, and then pull up the "Organize Usings" sub-menu: You can use this to alphabetically sort your namespaces (one of my pet peeves), and optionally use the 'Remove Unused Usings" command to remove un-necessary namespace declarations from the file: When you use this command the editor will analyze what types you are using in your code file, and automatically remove those namespaces that are declared but not needed to support them. A small but handy little feature. Summary The above list of editor improvements is by no means exhaustive, but rather just a few small improvements I've played with in the last week. Post others you notice in the comments section of this post, and I'll try and do an update with more in the future. Thanks, Scott 
|
-
I'm very pleased to announce that the Beta 2 release of VS 2008 and .NET 3.5 Beta2 is now available for download. You can download the Visual Studio 2008 product here. You can alternatively download the smaller VS 2008 Express Editions here. VS 2008 and Visual Web Developer 2008 Express can be installed side-by-side with VS 2005. .NET 3.5 Beta2 also includes a go-live license which allows you to build and deploy applications into production. Very Important: Please read my "Installation Notes" at the bottom of this blog post for a few post-installation steps you must make to ensure everything runs well. One of these steps fixes a side-by-side issue we found with ASP.NET AJAX. Quick Tour of Some of the New Features for Web Development Over the last few months I've written several blog posts that discuss some of the new improvements in this release. Below is a quick summary list of several of them that I have already published. This list is by no means exhaustive - there are a lot more things I haven't had a chance to blog about yet (stay tuned for more posts!): VS 2008 Multi-Targeting Support VS 2008 enables you to build applications that target multiple versions of the .NET Framework. You can learn more about how this works from my blog post here: VS 2008 Web Designer and CSS Support VS 2008 includes a significantly improved HTML web designer. This delivers support for split-view editing, nested master pages, and great CSS integration. Below are two articles I've written that discuss this more: ASP.NET also has a new <asp:ListView> control that I'll be blogging about in the near future. It delivers very flexible support for data UI scenarios, and allows full customization of the markup emitted. It works nicely with the new CSS support in VS 2008. ASP.NET AJAX and JavaScript Support .NET 3.5 has ASP.NET AJAX built-in (and adds new features like UpdatePanel support with WebParts, WCF support for JSON, and a number of bug fixes and performance improvements). VS 2008 also has great support for integrating JavaScript and AJAX into your applications: I will be doing a blog post in the next few days that talks more about some of the ASP.NET AJAX specific improvements, as well as how to upgrade existing ASP.NET AJAX 1.0 applications to use them. Language Improvements and LINQ The new VB and C# compilers in VS 2008 deliver significant improvements to the languages. Both add functional programming concepts that enable you to write cleaner, terser, and more expressive code. These features also enable a new programming model we call LINQ (language integrated query) that makes querying and working with data a first-class programming concept with .NET. Below are some of the articles I've written that explore these new language features using C#: Data Access Improvements with LINQ to SQL LINQ to SQL is a built-in OR/M (object relational mapper) in .NET 3.5. It enables you to model relational databases using a .NET object model. You can then query the database using LINQ, as well as update/insert/delete data from it. LINQ to SQL fully supports transactions, views, and stored procedures. It also provides an easy way to integrate business logic and validation rules into your data model. Below are some of the articles I've written that explore how to use it: I'll be adding several more articles to my series above in the weeks ahead. I think you'll find that LINQ to SQL makes it dramatically easier to build much cleaner data models, and write much cleaner data code. Lots of other improvements The list above is only a small set of the improvements coming. For client development VS 2008 includes WPF designer and project support. ClickOnce and WPF XBAPs now work with FireFox. WinForms and WPF projects can also now use the ASP.NET Application Services (Membership, Roles, Profile) for roaming user data. Office development is much richer - including support for integrating with the Office 2007 ribbon. WCF and Workflow projects and designers are included in VS 2008. Unit testing support is now much faster and included in VS Professional (and no longer just VSTS). Continuous Integration support is now built-in with TFS. AJAX web testing (unit and load) is now supported in the VS Test SKU. And there is much, much more... Important Installation Notes - PLEASE READ! There are two important things you should do immediately after installing VS 2008 and .NET 3.5 Beta2: 1) You should download and run this batch file. This takes only a few seconds to run, and fixes an issue we found earlier this week with the version policy of System.Web.Extensions.dll - which is the assembly that contains ASP.NET AJAX. If you don't run this batch file, then existing ASP.NET 2.0 projects built with ASP.NET AJAX 1.0 and VS 2005 will end up automatically picking up the new version of ASP.NET AJAX that ships in .NET 3.5 Beta2. This will work and run fine - but cause you to inadvertently introduce a .NET 3.5 dependency in the applications you build with VS 2005. Running the batch file will change the version binding policy of the new System.Web.Extensions.dll assembly and ensure that you only use the new .NET 3.5 ASP.NET AJAX version with projects that you are explicitly building for .NET 3.5. 2) If you have ever installed a previous version of "Orcas" or VS 2008 on your machine (either Beta1 or one of the CTP versions), you need to reset your VS 2008 settings after installing Beta2. If you don't do this, you'll have an odd set of settings configured (some windows will be in the wrong place), and you'll potentially see some IDE performance slowness. You can reset your settings by typing "DevEnv /resetsettings" on the command-line against the VS 2008 version of the IDE: Summary There are a lot of new improvements and enhancements that I hope you'll find really useful with VS 2008 and .NET 3.5. Stay tuned to my blog over the next few weeks as I'll be posting more about some of the new features and how to get the most out of them. Thanks, Scott 
|
|
|
|