Jaycent Drysdale

asp.net mvc page compression

Looking for a great way to reduce page size and reduce bandwith usage on your asp.net mvc web application?
consider looking into page compression. Below is the c# class that I used to knock my page size down from 44K to a measly 6K...thus saving on bandwidth usage and page download time. 

First, you need to reference the following namespaces


using System.IO.Compression;
using System.Web;
using System.Web.Mvc;


And then you throw this class together, subclassed by ActionFilterAttribute

public class EnableCompressionAttribute : ActionFilterAttribute
const CompressionMode compress = CompressionMode.Compress;
public override void OnActionExecuting(ActionExecutingContext filterContext)
HttpRequestBase request = filterContext.HttpContext.Request;
       HttpResponseBase response = filterContext.HttpContext.Response;
       string acceptEncoding = request.Headers["Accept-Encoding"];
       if (acceptEncoding == null)
else if (acceptEncoding.ToLower().Contains("gzip"))
             response.Filter =
new GZipStream(response.Filter, compress);
"Content-Encoding", "gzip");
else if (acceptEncoding.ToLower().Contains("deflate"))
             response.Filter =
new DeflateStream(response.Filter, compress);
"Content-Encoding", "deflate");

then decorate your Controller Methods like so:

public ActionResult Index(string id)

Refresh your page and be prepared to be knowcked off your rockers in terms of the dramatic chnage in page size.

Now this should work in all modern browsers, but for some reason, the latest distribution of Internet Explorer is totally out of the loop as far as this goes.
But it does work with latest version of Opera, Firefox, Safari, Chrome. 

For further reading, check out this article regarding page compression.



Posted: Feb 21 2010, 07:00 AM by jaycent | with 13 comment(s)
Filed under: ,
Quick and easy way to get cpu, screen resolution, and RAM information in a windows form application.

Quick and easy way to get cpu, screen resolution, and RAM information in a windows form application.

First, add the follwoing namespaces

using Microsoft.Win32;

using System.Management;


once you add those,  you are good to go:

        string cpu = string.Empty;
         string screenResolution = string.Empty;
         string ramSizeInGigaBytes = string.Empty;
         string ramSizeInKiloBytes = string.Empty;

         //get the screen resolution
         screenResolution = string.Format("{0} by {1}", SystemInformation.PrimaryMonitorSize.Width.ToString(), SystemInformation.PrimaryMonitorSize.Height.ToString());

         //get CPU info
         RegistryKey RegKey = Registry.LocalMachine;
         RegKey = RegKey.OpenSubKey("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
         Object cpuSpeed = RegKey.GetValue("~MHz");
         Object cpuType = RegKey.GetValue("VendorIdentifier");
         cpu = string.Format("{0} - {1} MHz.", cpuType, cpuSpeed);

         //get RAM
         ManagementObjectSearcher Search = new ManagementObjectSearcher("Select * From Win32_ComputerSystem");
         foreach (ManagementObject Mobject in Search.Get())
         { double Ram_Bytes = (Convert.ToDouble(Mobject["TotalPhysicalMemory"]));
            ramSizeInKiloBytes =  (Ram_Bytes / 1024).ToString();
            ramSizeInGigaBytes = (Ram_Bytes / 1073741824).ToString();

         MessageBox.Show("cpu: " + cpu);
         MessageBox.Show("screen res: " + screenResolution);
         MessageBox.Show("ram KB: " + ramSizeInKiloBytes);
         MessageBox.Show("ram GB: " + ramSizeInGigaBytes);



List<t> paging via LINQ to Objects

The various grid controls shipped with asp.net provides plug and play data paging on its underlying data source. Its quiet simple to get a paged view of your data by setting a few properties on the grid before calling the Bind() method to connect your grid to the data.  This scenario works well in most situations. On occasions where the paging logic needs to reside outside of the UI layer, a more custom paging mechanism is required.

In this post, I'll examine a simple way to implement a custom paginging mechanism via LINQ to objects, removing the paging logic from the UI component and placing it at a lower level layer, maybe in a controller class (MVC) or in a presenter class in an MVP pattern.

Lets imagine we have just retrieved a list of 5,000 rows of data from a product catalog table living in a SQL Server 2005 database, via a datatable object. The data retrieved is broken out into the following columns:

ProductId (int)
Name (string)
Description (string)
Price (decimal)
Category (string)

We first need to convert this datatable object to a strongly typed list of product summaries (each row in the datatable = a product summary)

Lets define a product summary class that we can map each product to:

public class ProductSummary
public int ProductId { get; set; }
      public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }

We will also define another method that takes the datatable object and convert it into a strongly typed list of ProductSummary Instances.

public List<ProductSummary> ConvertTableToList(DataTable aDataTable)
List<ProductSummary> _lst = new List<ProductSummary>();
foreach (DataRow aDataRow in aDataTable.Rows)
ProductSummary aSummary = new ProductSummary();
          aSummary.Category = aDataRow[
          aSummary.Description = aDataRow[
          aSummary.Name = aDataRow[
          aSummary.Price = (
          aSummary.ProductId = (
return _lst;

So far we have created a class ProductSummary that will hold a row of data from our datatable. We have also defined a method called ConvertTableToList that will take our datatable object and convert it into a list of Productsummary objects.

public static List<ProductSummary> GetProducts(int? page, int? pageSize)
     //default to page 1 if no page supplied
int _page = (page.HasValue) ? page.Value : 1;

     DataTable dt = PupulateDataTable() //replace PopulateDataTable() with your logic to retrieve the data from the underlying data store

     //if no page size specified, set page size to total # of rows in data table
int _pagesize = (pageSize.HasValue) ? pageSize.Value : dt.Rows.Count;

List<ProductSummary> lst = ConvertTableToList(dt);     

     //paging logic
     return lst.Skip((_page - 1) * _pagesize).Take(_pagesize).ToList();

And here is how we might access a page of data from an asp.net web form page code-behind using the method defined above.
Assume that our paging method was  defined in a class called Products. Here we are retrieving page one, and we are telling the method to return 50 rows of data per page.

List<ProductSummary> products = Products.GetProducts(1, 50);
foreach (ProductSummary aSummary in products)
string.Format("{0} {1} [{2}]","<li>",aSummary.Name, aSummary.Category));
products =


Posted: Jul 13 2009, 07:01 AM by jaycent | with no comments
Filed under: , , ,
Generate RSS/Atom feeds using FeedManager.dll

FeedManager is a custom RSS/Atom Syndication generator that allows for quick and efficient generation of RSS/Atom feeds. Just reference the dll in your web applications, then write a few lines of code to expose your data to external applications/web sites.

The rsstoolkit exists for generating syndicated feeds on the fly, but if, like me, you have had issues porting the toolkit between project types and have to keep messing with web.config settings to get it to work, then the feedmanager.dll approach might work for you. 

 Here's how to get started:

  1. Download the cutsom FeedManager.dll here.
  2. Add a reference to the dll from your solution, or simply copy the file to your application's Bin directory
  3. Open up a web page, and in the code behind, create an instance of the FeedManager.FeedCreator class
  4. Set Properties on the FeedCreator class (title, author etc)
  5. Add FeedItems to the FeedCreator class. This will typically be data obtained from a dataset.
  6. Call the GenerateFeed() Method on the FeedManager.FeedCreator class to generate your feed.
    protected void Page_Load(object sender, EventArgs e)
using (FeedManager.FeedCreator aFeed = new FeedManager.FeedCreator(FeedType.RSS))
aFeed.FeedUrl = "http://www.solid2.com";
aFeed.FeedTitle = "My RSS Feed Title";
aFeed.FeedDescription = "My RSS Feed Description";
aFeed.FeedCopyright = "(c) 2009. All rights reserved";
aFeed.FeedImage = "http://contoso/image.jpg";

//add items to the feed
aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "first Item", "first summary", "Lorem ipsum dolor sit amet.", "thefirstlink", "1.aspx", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));
aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "second Item", "second summary", "Lorem ipsum dolor sit amet.", "thesecondlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));
aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "third Item", "third summary", "Lorem ipsum dolor sit amet.", "thethirdlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));
aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "fourth Item", "fourth summary", "Lorem ipsum dolor sit amet.", "thefourthlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));
aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "fifth Item", "fifth summary", "Lorem ipsum dolor sit amet.", "thefifthlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));
aFeed.AddItem(new FeedItem(Guid.NewGuid().ToString(), "sixth Item", "sixth summary", "Lorem ipsum dolor sit amet.", "thesixthlink", "http://www.solid2.com", DateTime.Now.ToString(), "Jaycent", "info@solid2.com"));

//generate the feed, send results to browser window.

Navigate to the page to view the ouput! 

Play around with setting the FeedType setting in the constructor between Feedtype.RSS and FeedType.Atom. View the source of the generated file to examine the difference in the output. For an excellent comparison article for ATOM vs RSS, see Aaron Brazell  article here.

 Happy new year, and happy programming!

System.Data.GenericClient : A custom Data Access Component

Developers often find themselves having to connect to data in a variety of datasources ranging from MS Access  to large scale relational databases such as Oracle, SQL Server, MySql etc. Each different datasource type typically requires importing a different .Net provider-specific namespace for working wth a specific database. For instance, to connect to an Oracle Database the consuming application needs to import the System.Data.OracleClient Namespace and untilize classes such as OracleCommand, OracleDateReader etcettera. To connect to SqlServer applications developers import the  System.Data.SqlClient namespace into their applications and program against the classes provided by the namespace.  The net effect of having multpile provider specific namespaces is that your DAL components are rarely ever portable, with each different database type normally requiring provider specific code.

System.Data.GenericClient is a simple but generic custom built data access component that solves some of the issues outlined above. System.Data.GenericClient provides a very simple but familiar API that can be configured declaratively in an application configuration file as well as programmatically in your DAL. Below I'll take a look at using System.Data.Generic to connect to various datasources using a consistent API.

Here's what you need to do to get started using System.Data.GenericClient in your applications:

  1. Download the zip file at the link provided below . Extract the contents, then add a reference in your application to the extracted System.Data.GenericClient.dll file.

  2. Open up your aspplications config file and declare an appsettings entry as shown below:
    add key="System.Data.GenericClient.DefaultConnectionStringName" value="mysqlConnectionString" />

  3. Declare a connectionstring entry. Make sure the name of this connection string matches the appsettings entry value specified above. In this case, the connectionstring entry name should be specified as "mysqlConnectionString. Provide a valid MySql Connection string. See example below:

    add name="mysqlConnectionString"
    connectionString="Network Address=serveradress;
    Catalog='mydb';User Name='sa';Password='pwd'" 
    ="MySql.Data.MySqlClient" />

  4. Write data access logic to connect to the database. Below is an example of how to return a datatable object from the datasource

    using (System.Data.GenericClient gClnt = new GenericClient())
         gClnt.Command.CommandType = CommandType.Text;
         gClnt.Command.CommandText =
    "select * from employees";
    using (DataTable dt = gClnt.ExecuteDataTable())
    this.dataGridView1.DataSource = dt;

The code snippet above shows how simple it is to use System.Data.GenericClient to access data from mySQL in a provider independent format.  For each aditional datasource your application needs to connect to, specify a valid connection string in the applications configuration file as outlined above, then specify a valid command text or stored procedure on GenericClient's command object. 

See below for a list of operations supported by the GenericClient object:

  1. public virtual int ExecuteNonQuery()
    Use this method to execute an update, insert or delete operation on the underlying datasource

  2. public virtual string ExecuteXML()
    Use this method to execute a query on the underlying datasource. Returns data in xml format

  3. public virtual DataTable ExecuteDataTable()
    Use this method to execute a query on the underlying datasource. Returns a datatable object

  4. public virtual object ExecuteScalar()
    Use this method to execute a query on the underlying datasource. Returns a scalar object

System.Data.GenericClient remains a work in progress. In addition to the features highlighted above, you will find other features in the namespace. These and other features will be further refined and documented in future updates.

File Download: System.Data.GenericClient.zip 

Want a copy of the source code? Send email to jaycentdrysdale@hotmail.com

File System search via LINQ to Objects

LINQ provides a standard way for developers to query data in diverse locations, ranging from in memory objects, XML data, or relational data living in an SQL Server Database.Lets take a look at a scenario where we use Linq to objects to query a directory on the local drive for files that match a given extension, and show the results in a Datagrid control.

Here is the plan of action for the application

  1. Create a function to return a list of all the files in a directory.  We will call this method GetFiles, it will take one string parameter representing the base search directory, and will return a strongly typed list of FileInfo Objects.
  2. Use Linq to Objects to filter the returned list for files that matches a user-specified file extension.
  3. Bind the results to a grid
Lets start by taking a look at the GetFiles function:

static System.Collections.Generic.List<FileInfo> GetFiles(string sPath, string sFileExtension)
DirectoryInfo _dirInfo = new DirectoryInfo(sPath);
return System.Linq.Enumerable.ToList(_dirInfo.GetFiles(string.Format("*{0}",sFileExtension), SearchOption.AllDirectories));

The GetFiles() function uses objects from the System.IO namespace to do the heavy lifting of searching the file system. Results are returned in a strongly typed list of FileInfo Objects.

Next we will look at the code that calls the GetFiles method defined above, and uses Linq to filter the list for the given file type. You would typically put this code in the click event for a button control on a windows form.

//get all files contained in the path supplied by the user
System.Collections.Generic.List<FileInfo> _theFiles = GetFiles(c:\myDirectory, ".doc"); 

//we now have a list of files...next we use LINQ to query the file list and sort the results by name
var _files = from file in _theFiles 
orderby file.Name 
select file;

this.dataGridView1.DataSource = _files.ToList();

And there you have it. Note the use of the orderby clause to sort the results before you bind the results to the grid. 

Posted: Feb 15 2008, 11:21 AM by jaycent | with 26 comment(s) |
Filed under: , , ,
Extension Methods: A simple example

If you've been developing software for any significant lenght of time, chances are you have compiled(for want of a better word) a repository of helper functions that have, over time, become valuable to you as you make your way through various applications. Extension Methods allow us to extend our custom and existing CLR types to include new functionality. These new functionality might already exist in the form of helper functions scattered throughtout our applications. For example, You might have a helper function that converts a string value to Proper Case. Extension methods allow us to "add" this ToProperCase() functionality to the primitive System.String type as if it were a built in method of the type. 

In this post, I'll share with you a simple example of how I used extension methods to extend the sealed System.DateTime native type to include a
ToFriendlyDateString() method. Extension Methods are new in the .Net Framework 3.5.

The idea behind the ToFriendlyDateString() method is representing dates in a user friendly way. For example, when displaying a news article on a webpage, 
you might want articles that were published one day ago to have their publish dates represented as "yesterday at 12:30 PM". Or if the article was publish today,
show the date as "Today, 3:33 PM". 

The code snippet below shows the logic that will represent our extension method. Note the Namespace declaration, and the signature for the class definition. Note also the use of the this keyword when describing the input parameter for the ToFriendlyDateString() method. I'll eloberate on these later in this discussion.

namespace Utils
     public static class Extensions
public static string ToFriendlyDateString(this DateTime Date) 
string FormattedDate = "";
if (Date.Date == DateTime.Today)
                           FormattedDate =
else if (Date.Date == DateTime.Today.AddDays(-1)) 
                           FormattedDate =
else if (Date.Date > DateTime.Today.AddDays(-6))
                           // *** Show the Day of the week
FormattedDate = Date.ToString("dddd").ToString(); 
                          FormattedDate = Date.ToString(
"MMMM dd, yyyy");

//append the time portion to the output
FormattedDate += " @ " + Date.ToString("t").ToLower();
return FormattedDate; 

When creating extension methods, here are the rules

  • You must define a namespace for your class.  Utils in the snippet above (Namespaces are not a strict requirement, but good practice nevertheless)
  • The class that contain the extension method must be decorated with the static modifier, and its visibility must be public
  • The class must contain a static member, which will act as the extension method. This method must be public and must take one or more parameters, the first which must be a derivitive of the type you are extending. The first parameter definition must be preceeded by the this keyword

Extension methods are defined as static methods but are called by using instance method syntax. Their first parameter specifies which type the method operates on, and the parameter is preceded by the this modifier. Extension methods are only in scope when you explicitly import the namespace into your source code with a using directive. See example below showing how we might use the ToFriendlyDateString() method in our applications:

using Utils;


DateTime dt = new DateTime(2008, 2, 10, 8, 48, 20);

For further details on Extension Methods, check out this MSDN link: http://msdn2.microsoft.com/en-us/library/bb383977.aspx

Object Oriented Programming Refresher

Recently I was challenged by a colleague who asked some very basic questions relating to object orient programming. I know these concepts very well, but sometimes you have to stop and think twice about them, especially if most often than not, you do not implement these concepts in your day to day programming activities. As developers, we often find ourselves in situations where the need to get things out the door and into production tend to encourage us to not think about doing things the right way, but instead, getting the work done in the least possible time.  Object Oriented concepts are something every serious developer should know inside out. Sure you can get by without practicing it, but that approach might come back to haunt you down the road.

Classes are the foundation of Object Oriented Programming. Business Logic code should be seperated into groups of related classes that satisfy a business need. There should be a clear seperation of concerns. When planning a development strategy for our applications, we should at all times try to envision our applications as being seperated into three logical tiers. Strictly speaking, having three logical tiers doesnt dictate that our apps must to be deployed physically as a three tier app...all the tiers could live on one one physical machine, or they could be deployed accross three different machines. They could also be deployed on multiple machines in the enterprise, in what is known as an n-tier architecture.  Our apps will perform much better when we distribute the processing requirements accross multiple machines...business logic components run on machine A, Data Access components run seperate machine, and the front end logic running on a clinet pc or web server somewhere else. Microsft Transaction Server, and now Enterpise Services can act as a broker for our components living in the data access and business logic tiers, and offer such services as transactions support, object pooling, which promotes better scaling applications.

So, what is an abstract class. What is a sealed class. What is the difference accessibility methods out there that I can apply to my classes and methods, and why do I need them? What are interfaces? when is it useful to use an interface? These are the questions that rolled through my head when I was first introduced to OOP years ago. Over time, as you develop more business level applications, the importance of these concepts become clearer.

Inheritance is a pupular term among the OOP purists. So what is Inheritance, and how does it relate to OOP? Perhaps the best way to describe this would be to imagine a hypothetical situation where you are building an app that requires you to Mainatin a list of employee records. All employees must have an employeeID, they must have a first name, and they must have a departmentID etc. In addition, there are some employees that work on a part-time basis, and some that work full-time.

Looking at the above scenario, we have indentified the need for an employee class to service our application. but before we start building our employee class, we need to take a closer look at how that class will be implemented. There are common features that all employees have, but there are also some features that are specific to  the full-time employee and others that are specific to the part-time employee. For instance, when we calculate the monthly pay for the full-time employee, the logic might be different from what we do when we calculate the salary of the guy that is employed part-time.  It might help if we define a baseline Employee class that contain the common functionality, properties etc, and then further extend these classes in other derived classes to inplement the specific functionality. So at the root, we might create an employee class,  and two derived classes: FullTimeEmployee and ParttimeEmployee. Both these classes will be based on the base Employee class and will inherit any functionality exposed, but will further provide indiviual methods that will be used to calculate an employee's salary.

By marking our employee class as Abstract, we are marking it as a class that cannot be instantiated directly...we are saying that this class exists only to be further refined through inheritance. The exact opposite scenario to that would be to mark our class as sealed, which would mean it cannot be further refined through inheritance.

The definition for our base employee class might look like this:

public abstract class Employee

The definiton for the derived classes might look like so:

sealed class PartTimeEmployee:Employee

public sealed class FullTimeEmployee:Employee

Selected data and function members defined in the Employee class will be avaialable in both the derived classes. Data Members such as firstname, lastname, deptID, employeeID are common to all employees are defined on the Employee base class. The Employee base class will also contain a method called CalculateWages, which will contain no functionality, but will tell any class that implements the Employee class that it must implement a CalculateWages method. In the base class, the signature for the calculateWages Method might look like this: 

abstract decimal CalculateWages();

The CalculateWage() method in the base Employee class could alternatively be decorated with the virtual modifier instead of abstract. The difference is that the virtual modifier allows the base class to put implementation code in the method, and allows the derived class to decide wether or not it wants to override the implemementation provided by the base class. If the derived class wants to overide the method in the base class, it would implement the method using the following signature:

public override decimal CalculateWages()

The scenario looked at above describes a very simple example of how we might implement a simple employee class in one of our applications. Of course, there is much more to object oriented programming, to much to be described in a single blog post. Of course, there are many different ways to implement OOP...for instance, the employee base class described above could be implemented as an interface instead of as an abstract class. 

In Part 2 of this 4 part series, I'll take a look at other class modifiers, and also some of the accessibility options that we have available for exposing our classes to the outside world and what they mean for our classes. I'll also take a look at Interfaces, and how they can be used in the Employee list management scenario described in this article.

Anticipated new Data Types in Microsoft SQL Server 2008

The next release of Microsoft SQL server, version 2008, promises a number of significant changes over its previous 2005 version release.  From a Developers perspective, there is much anticipation over the new data types that we will get to play with in our stored procedures and other database objects. I’ll go through some of the new data types in this post.

New Date data types:
Date:-The new Date data type allows you to store dates without a time component from 0001-01-01 to 9999-01-01. This new type will lend itself well to situations where a date variable doesn’t need to have a time attached to it...like a date of birth field/variable. There is also the Time type, which as you might guess, stores a time value, minus a date portion. Already I'm seeing situations where these Data types would have saved me a few lines of code had hey been available earlier. Other new date types include DateTime2 and DatetimeOffset.

New HierarchyId data type
According to the Microsoft documentation, the Hierarchyid is a new data type that can store values that represent nodes in a hierarchy tree. This data type, which has a flexible programming model, can be implemented as a Common Language Runtime User-Defined Type (CLR UDT). The CLR UDT exposes several efficient built-in methods for creating and operating on hierarchy nodes. I am eagerly awaiting further details on the use of this new type, but at first glance, it seems we will now be able to store the hierarchical metadata that describes things like menu trees etc in a format that is easily retrievable. Building menus etc could be as easy as binding a treeview control to a field returned from a database or web-method call. I hope my understanding of this new type is not too far off from what it actually is. Time will tell.

UserDefined Table type:
Again, the Microsoft documentation described this new type as follows: A user-defined table type represents the definition of a table structure. You can use a user-defined table type to declare table-value parameters for stored procedures or functions. You can use this table type to declare table variables that are to be used in a batch or in the body of a stored procedure or function. To ensure that the data in the table type meets specific requirements, you should create unique constraints and primary keys on the table type. Actually, this is a neat addition. If I understand this correctly, we can pass in an array (table) of parameter items into a stored procedure as a unit. So instead of passing in 50 individual parameters into a Stored Procedure, It’s now possible to pass in a single UDT type that holds all 50 parameter bits that need to get to the Query.

Now here is where it gets interesting. It’s now possible to store data directly to the file system on the server via the FILESTREAM data type. It allows you to store unstructured data directly in the file system. You can use the new storage type VARBINARY(MAX) FILESTREAM to define table columns and store large binary data as files in the file system instead of storing them as Binary Large Objects (Blobs). In addition, you can use T-SQL statements—SELECT, INSERT, UPDATE, or DELETE—to query and modify FILESTREAM data. You can use the rich set of streaming APIs provided by Win32 for better streaming performance, while maintaining transactional consistency. You can also apply SQL Server functionalities to FILESTREAM data such as triggers, full-text search, backup and restore, SQL permissions, Database Console Command (DBCC) checks, and replication.

Sparse Columns
Typically, if you have a column/field in your database table that is infrequently used, and contains a null value in most cases, the new Sparse Columns feature provides a more efficient way to represent these.

In wrapping up, its also worth mentioning that the UDT types, introduced in SQL Server 2005, have undergone some changes in the 2008 release. Previously UDT types were limited a size of 8K....that limitation has been removed.

Posted: Jan 31 2008, 03:29 PM by jaycent | with 1 comment(s) |
Filed under:
Options for Database access outside of ADO.Net

In the world of .NET programming, ADO.NET has become the De Facto standard for accessing database of all types (relational or otherwise). The purists among us will be quick to point out that ADO.Net should be the only option and that as developers we shouldn’t even be thinking about bypassing ADO.NET to get to our database. But the no-so-pure will be quick to point out the alternative methods for pulling data from our databases without writing a line of database code. If you are still reading this article, it means you, like your truly have had occasions in the past where bypassing ADO.Net makes sense, whether you are creating a small website for your wedding guest list, or just putting together a demo website of sorts.

The SqlDataSource Control:
The SqlDataSource control (in my mind, the grand-daddy of declarative data Access) allows for the definition of queries in a declarative way. You can connect the SqlDataSource to controls such as the Datalist, and give your users the option to edit and update data without requiring any ADO.NET code.  While the sqlDatasource control handles the heavy lifting required to facilitate the communication, it's worth mentioning that behind the scenes, it uses ADO.NET to do this heavy-lifting. The sqlDatasource supports any database that has a full ADO.NET provider. Apart from the fact that the sqlDatasource connects you to your database with minimal code, it does provide more benefits to developers who are looking to provide functionality such as paging sorting of datagrids without having to write lines of code to achieve this. If you bind your datagrid directly to a sqlDatasource control, you have paging and sorting functionality right at your fingertips.  You can get to it by setting a few properties on your grid control. However, with all its "niceties" the SqlDataSource is somewhat controversial, because it encourages you to place database logic in the markup portion of your page. Many will agree that there are times when the benefits of using this control far outweigh this particular drawback.

Linq provides us with cool new way of accessing data.  The source of this data can range from anything from files in your computer file system, a collection of objects living in a generic list in server memory, or rows of data residing in a database table in on the North Pole. Linq comes in a variety of flavors (LINQ to objects, LINQ to XML, LINQ to entities, LINQ to SQL, LINQ to Dataset).  With LINQ to SQL, you define a query using C# code (or the LinqDataSource control) and the appropriate database logic is generated automatically. LINQ to SQL supports updates, generates secure and well-written SQL statements, and provides some customizability. Like the SQLDataSource control, LINQ to SQL doesn’t allow you to execute database commands that don’t map to straightforward queries and updates
(such as creating tables). Unlike the SqlDataSource control, LINQ to SQL only works with SQL Server and is completely independent of ADO.NET.

The profiles feature, introduced in .Net Framework 2.0, allows you to store user-specific blocks of data in a database without writing
ADO.NET code.  You specify what data you want to gather and store by configuring the appropriate elements in your applications configuration file.

In wrapping up, it’s worth mentioning that none of options presented in this article is a replacement for ADO.NET, because none of them offers the full flexibility, customizability, and performance that hand-written database code offers. However, depending on the specific needs of your application, it may be
worth using one or more of these features to augment your ADO.Net centric data access layer.

Posted: Jan 29 2008, 09:47 AM by jaycent | with 2 comment(s) |
Filed under: , , , ,
More Posts Next page »