Andres Aguiar's Weblog

Just My Code

DLINQ ASP.NET Build Provider and DLINQ DataSource

In the pnp Summit West there was a 'GotDotNet CodeSlam'.

I've been thinking that DLinQ  + ASP.NET 2.0 Build Providers could give us a very easy, rubyonrails-esque kind of programming, and driving back to the hotel I thought of the obvious way of mixing both.

What I built for the CodeSlam (by the way, people did not seem to like it much, as it did not win any prize ;), but I still think it's cool), is a Build provider for DLinQ. Basically, you add a file with a .linq extension to the App_code folder, with the following format:

<DLinQGenerator>
    <
connectionString>server=.;trusted_connection=yes;database=northwind</connectionString>
    <
namespace>DataAccess</namespace>
    <
className>Northwind</className>
</
DLinQGenerator>

Then, without any further work I can write an aspx page like:

<% DataAccess.Northwind db = new DataAccess.Northwind(); 
     var one = from customer in db.Customers
     select new {customer.ContactName, customer.Phone};  %>

<table>
<% foreach (var x in one) { %>
<tr>
<td> <%= x.ContactName %></td>
<td> <%= x.Phone %></td>
</tr>
<% } %>
</table>

The build provider generates a CodeDom that has the DLinQ classes for the database, and ASP.NET gives you intellisense... cool! The only trick is that to generate the CodeDom, I dissasembled the 'sqlmetal' tool distributed with LinQ so I could use some internal methods that already built the CodeDom tree, so the implementation was actually quite easy.

Note that this could overcome some of the perceived limitations on DLinQ, for example, even if you are using attributes in the classes to make DLinQ work, you could generate different attributes depending on the database you want to use, or some other strategy.

With that you can display data, but what about updating? To have two-way databinding over a moderatley interesting data source in ASP.NET you need to implement your own ASP.NET DataSource, so I wrote one for DLinQ classes (the source is in the gotdotnet workspace).

The main problem is that I need to use generics to create the DataSource control to be able to use DLinQ in it (I tried without generics and I did not find a way to do it, but if you find it let me know). If you use generics in an ASP.NET control then you can not create it in the .aspx page! :( :( :(. So, instead of having a nice declarative way to create it, you need to write code:

DLinQDataSource<DataAccess.Products> dataSource = new DLinQDataSource<DataAccess.Products>();

dataSource.ID = "dataSource1";
dataSource.Table = productList;
dataSource.DataContext = db;

Controls.Add(dataSource);

this.GridView1.DataSourceID = "dataSource1";

If you update/insert/update with the GridView, it will use the DLinQ classes to persist the data. It will keep the DataContext in the session or viewstate to be able to update it. The DataSource implementation is kind of interesting as you need to manually build ExpressionTrees to use the DataSource information sent in the ExecuteSelect/Update/Insert/Delete methods to be able to retrieve the right instance from the DataContext and then submit the changes.

 

Comments

No Comments