Windows DevCenter    
 Published on Windows DevCenter (http://www.windowsdevcenter.com/)
 See this if you're having trouble printing code examples


Build Dynamic Database Applications in .NET with Project Codename "Jasper"

by Julia Lerman
07/31/2007

Dynamic programming has become more popular as developers look for simpler ways to do Rapid Application Development (RAD) of database applications. Ruby on Rails is a great example of this for web applications, and its rise in popularity is proof of its value to developers. But instead of moving to Ruby on Rails, ASP.NET developers might consider Project Codename "Jasper" and the growing number of .NET dynamic languages, including Iron Python, IronRuby, and Visual Basic.

Project Codename "Jasper" is a new incubation project for building dynamic applications---programs that practically create themselves on the fly--that was unveiled at MIX07 in Las Vegas this past spring by Microsoft's Data Programmability team.

Jasper and technologies such as Rails favor "Convention over Configuration." The idea behind this concept is that a developer should only have to write code for behavior in an application that is "unconventional." With databases and other data stores, a lot of assumptions can be made based on their metadata and schemas. For example, a program might assume that if an Employees table has the fields FirstName, LastName, StartDate, and an Auto-Incremented Primary Key field of ID, then a form could be created to add, edit, or delete an individual row using the Primary Key to synch modifications to the database. If there is a Primary Key/Foreign Key relationship between that table and another, then the program would create a master/detail form between the two tables. However, if you wanted to do something different, such as not include StartDate in the data entry form, or pull in data from related tables, that would be considered "unconventional". The only code you should need to write is for behavior that does not follow "conventional" assumptions.

One of the features of the existing frameworks, such as Ruby on Rails and Django, is that they rely on the schema of the actual data store (such as a database or XML files), which they can inspect and then use to define forms and reports. Often, these storage schemas are structured to support efficiency and security, rather than organizing data so that it aligns nicely with the developers' business model.

Jasper and the ADO.NET Entity Framework

What makes Jasper different from these other web application frameworks is that, rather than depending directly on the database for its schema, it uses an Entity Data Model created by the ADO.NET Entity Framework.

The Entity Framework is the core of Microsoft's evolving data access platform. It is currently in Beta and will be released in the first half of 2008 as an out-of-band set of APIs for Visual Studio 2008. The Entity Framework codifies the use of Entity Relationship Models, which have, for the past 30 years, lived mostly on whiteboards. These models can be designed to represent a data schema in a way that is more appealing to developers without impacting the database. APIs then allow a developer to write code against his conceptual model, while mapping and data store schemas are used to coordinate the movement of data back and forth to the database. This is not the same as ORM tools because the Entity Framework does not create a tight binding between business objects and the database. The Entity Data Model is a layer of abstraction in between objects and the database or some cases, in between a presentation layer and the database. Entities only represent data schema. Unlike objects, they do not define behavior.

Jasper's use of the Entity Data Model instead of connecting directly to the database means that there will be fewer anomalies to manually code around. For example, if the database was normalized so that contact details are spread across a number of tables (contacts, emails, telephones, and addresses) you could customize a model so that all of this information is contained in one entity. Then when you create a dynamic application, a detailed contact record will be created automatically and not require custom code. Much more of the application can be truly dynamic.

Downloading the Jasper Preview

A Community Technical Preview (CTP) of Jasper has been available from Microsoft a CTP since its release at MIX07. The Jasper CTP comes with a few dozen examples and can be downloaded here. Be sure to read the overview document for additional installation requirements and instructions.

Because of the dynamic nature of Jasper, it is necessary to use a dynamic language; Microsoft has been busy creating some of those as well and, of course, there's Visual Basic.NET (VB10 will be a dynamic language). Half of the samples in the CTP use Visual Basic.NET, while the other set of samples use the Iron Python language. Microsoft's new Ruby implementation, IronRuby, should work with Jasper in a future release, but was not ready for this CTP release. Because C# and other static languages perform type checking, they cannot be used with Jasper.

A Jasper Web Application

Let's take a quick look at a data-centric web application that uses Visual Basic and Jasper.

There are very few steps involved. First you will create an editable grid view of product data, then, with a few tweaks, you can turn the grid view into an editable master/detail view. While you can just read through the steps to get the concept of how you go about creating a web application using Jasper, if you wish to build this demo, you'll need to install the Visual Studio 2008 Beta1 and the Jasper CTP as described in the previous section.

  1. Create a web page like the one shown in Figure 1 by dragging on to it both an ASP.NET databound control (such as a GridView) and a Microsoft.Jasper.AutoDataSource control from the Visual Studio toolbox. You can add the AutoDataSource control to the Toolbox by selecting Program Files\Microsoft Codename Jasper CTP\Binaries in the Toolbox wizard.

    Setting the ID of the GridView to "Products" tells the AutoDataSource all it needs to know. This property will be used to populate the GridView.

    Figure 1 shows what the completed page should look like in design view.

    Web page with GridView adn AutoDataSource
    Figure 1. Web page with GridView and AutoDataSource

  2. In the code-behind, you will need to create a Microsoft.Jasper.DynamicContext. The DynamicContext is an object that will track any changes the user makes to the data and also coordinate sending those changes back to the database. DynamicContext takes a database connection string as a parameter. The Jasper samples use a connection string in web.config that is set to point to the Northwind database (included in the CTP). The connection string has more information than you will see in a typical application. These additional parameters are required for Entity Framework and Jasper. Check the Jasper documentation for more information about the connection string. The GetDynamicContext method below checks for the existence of the context in SessionState and creates it, if necessary. Note that in the current CTP, DynamicContext is not thread-safe.

    Private Function GetDynamicContext() As DynamicContext
         Dim context As DynamicContext = Session("DynamicContext")
         If context Is Nothing Then
             Dim connectionString As String = "Provider='System.Data.SqlClient';Provider Connection String='Data Source=.\SQLExpress;Initial Catalog=Northwind;Integrated Security=True;';Generate Default EDM=True;"
             context = DynamicContext.CreateDynamicContext(connectionString)
             Session("DynamicContext") = context
       End If
      Return context
    End Function
  3. The last step is to assign the DynamicContext to the AutoDataSource control on your web page. The AutoDataSource control orchestrates the binding of the data that is provided through the DynamicContext to the GridView. This is another example of how Jasper will use assumptions to do its job. AutoDataSource knows to look for a databound grid. It will see the GridView and assume that this must be the control to send the data to. Here I have implemented the assignment right in the Page_Load event.

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
          AutoDataSource1.DynamicContext = GetDynamicContext()
    End Sub
  4. Believe it or not, that's all that is required to render the page shown in Figure 2 with data that can be updated.

    Dynamically created web page
    Figure 2. Dynamically created web page

    Not Magic, Just Jasper

    So, what happened in between the few lines of code you wrote and the creation of this page?

    The DynamicContext control uses the Entity Framework APIs to automatically generate an Entity Data Model (EDM). The EDM is comprised of the schema files described above, and code generation is used to build a set of classes that represent the conceptual schema of your data. Each class, for example Customer or Product, is an Entity. Entity is a class in the Entity Framework's Object Services provided by the System.Data.Objects namespace. The first time Jasper builds the EDM there is a small performance hit, which is why it's a good idea to cache the context.

    The AutoDataSource then uses the concept of Convention to assume that because the GridView's ID is "Products," you must want to display the Product entities. The Entity Framework then coordinates the retrieval of the data. The results of an Entity Framework query can be bound directly to any databound control. In my example, the results are bound to the GridView, which, in turn, knows how to AutoGenerate columns based on the bound data.

    That's how the grid gets populated, but what about handling changes? The AutoDataSource has a property called PersistChanges which defaults to True. The Entity Framework's Object Services have change tracking built in, as well as the ability to save changes to the database. Together, the two can very easily handle updates. Again, because the updates in this sample are very conventional, Jasper does not force us to write code to make that happen.

    It is also possible to bind to a column rather than an entire table. Note that the current CTP does not have the ability to sort out common column names that appear in more than one table.

    Radder than RAD: A Master-Detail Page

    You can turn the example created above into a master/detail view by simply adding another GridView.

    By making the master GridView display Suppliers, a second Gridview can then display the Products for those suppliers. Knowing that there is a relationship between Suppliers and Products, we can assume that this will be exposed by Jasper as "Suppliers_Products." Jasper uses this construct for all relationships. By using this as the ID of the second GridView, Jasper, together with the AutoDataSource, can automatically create the Master Detail view displayed in Figure 3.

    Master Detail view
    Figure 3. Master Detail view

    Many web developers know the difficulty of coding a master detail form, so this is a pretty amazing feat! Again, the concept of convention comes into play here as Jasper is performing the most basic and unconventional function that can be assumed about handling data in a one-to-many relationship.

    Because this is a very early look at Jasper, I wasn't bothered by the fact that deleting a record in the master grid did not cause the children to be deleted. I know that Entity Framework is very smart about referential integrity and I am sure this will get worked out in future releases.

    Querying Data with Jasper

    Rather than always following the convention of grabbing data based on the ID of the databound control, the DynamicContext allows you to specify the data using a Microsoft.Jasper.Query class, Entity Framework's EntitySQL syntax, or even LINQ! In these cases, the AutoDataSource control is not necessary; the results of the queries can be directly bound to the databound controls. While LINQ is not yet supported directly by Jasper, it is still possible to use LINQ on the client side as demonstrated in the CTP samples.

    Jasper's Query class has methods similar to Extension Methods in LINQ including Where, First, GroupBy, OrderBy, and more. Here is an example of how you can use Jasper to return specific Customers.

    Dim context As Object = GetDynamicContext()
    Dim query As Query = context.Customers
    query = query.Where("it.Country = 'USA'")
    query = query.OrderBy("it.CompanyName")
    query = query.Select("it.CustomerID, it.CompanyName, it.City")
    GridView1.DataSource = query
    GridView1.DataBind()

    Because Jasper is using dynamic languages, LINQ uses late binding to perform its queries. At design time, the compiler has no knowledge of the schema or structure of the data classes that it will be working with, so you will be building the LINQ queries a little blindly without the help of strong typing and Intellisense. This is the dynamic language experience, not something specific to Jasper.

    Customizing Jasper

    While using Jasper out-of-the-box with a database will satisfy the needs of many solutions, it is possible to get more mileage out of Jasper without having to go back to standard applications. Check the CTP for examples of defining Business Logic, renaming items in the generated model, and also how to use a pre-created Entity Data Model.

    The ability to create a highly customized model, one that might be used in a variety of other applications in your enterprise, including SQL Server Reporting Services, then plug it into Jasper is another example of the bigger picture of the Entity Framework--Microsoft's evolving data access platform.

    Using Your Own Database

    If you plan to explore Jasper with your own databases, it's helpful to understand that each table in your database will have an entity type created whose name is the singular of the table name. An EntitySet is also created for each entity whose name is the plural of the table name. It is the EntitySet that is used for queries and for establishing the Dynamic Context. If you have a database table named "foo," you will use "foos" as the ID of a databound control.

    Next Steps

    There is a lot more to explore in the CTP, including building Windows Forms and the AutoBinder control, updating data and a set of Iron Python samples.

    Jasper is still in the very early stages of research and development and available for you to explore and question. Microsoft definitely wants feedback. The Jasper forum is a great place to ask questions and give further feedback on the product.

    With the popularity of frameworks such as Ruby on Rails, it is great to see Microsoft leveraging the strength of its Data Access platform to provide .NET developers with the ability to create dynamic applications in scenarios where even a drag-and-drop ASP.NET application seems like overkill. The addition of languages like IronRuby and Iron Python, will surely get a lot of non-Microsoft developers to take a look at using Jasper to build their web applications.

    Julia Lerman is the leading independent authority on the Entity Framework and has been using and teaching the technology since its inception two years ago. She is well known in the .NET community as a Microsoft MVP, ASPInsider and INETA Speaker. She is a prolific blogger, a frequent presenter at technical conferences around the world, including DevConnections and TechEd and she writes articles for many well-known technical publications.


    Return to WindowsDevCenter.com.

    Copyright © 2009 O'Reilly Media, Inc.