Solution:
Probably I should have created a user control with this dropdown and then used it across all pages! Ok, I did not think about it and I did not “anticipate” that I would have this control repeating in so many places.
Ok, what is the second option?
I have something called <asp:ObjectDataSource> in ASP.Net and probably that was a better option here because <asp:ObjectDataSource> forces me to use centralized (if I create them as centralized) functions from classes which I can pass and my SQL would remain in just one place. But still this requires a lot of lines of code in every aspx with parameters and the Datasource Config and other stuff. Also this is not a one place solution for controls that repeat in multiple pages [Except the Query, everything else repeats in every place]
So what other option I have? If only I had used a conventional binding using OOPS, with a separation of Business Logic/Data Access from my presentation then I would have been in a far better position!
How?
My aspx will just have just this - <asp:DropDownList ID="ddnCountry" SkinID="ddnBlue" runat="server">
In my Page_Load event of .CS page I will write
//Call GetCountryList Function which is in the FillControls Class of BLayer
BLayer.FillControls.GetCounrtyList(ddnCountry);
Following code is In BLayer: (Where Blyaer is either a namespace (folder) within the same project or a different project, depending on the project size, Etc)
/// <summary>
/// Function Which Generates the Query to Bind Country Value Across the Project
/// </summary>
/// <param name="ddnCountry"></param>
public static void GetCounrtyList(System.Web.UI.WebControls.DropDownList ddnCountry)
{
string sqlCountry = "SELECT [CountryRegionCode] As Value, [Name] As Text FROM Person.[CountryRegion] ORDER BY [Name]";
BindDropDowns(sqlCountry, ddnCountry);
}
/// <summary>
/// This Function accepts the Query to Bind and the Dropdown Control to Bind And then Binds the Dropdown Control. Can be called From Anywhere in the project.
/// </summary>
/// <param name="sqlCountry"></param>
/// <param name="ddnCountry"></param>
private static void BindDropDowns(string sqlToBind, System.Web.UI.WebControls.DropDownList ddnBind)
{
using (conAdvenWorks) //SQL Connection Object, Initialized with Connection String
{
conAdvenWorks.Open();
using (SqlCommand cmdDropDown = new SqlCommand(sqlToBind, conAdvenWorks)) //Command with the Query
{
ddnBind.DataSource = cmdDropDown.ExecuteReader(); //Command gets executed and is set as datasource to the control
ddnBind.DataTextField = "Text";
ddnBind.DataValueField = "Value";
ddnBind.DataBind();
}
}
}
Please note that the BindDropDowns function is common to Bind ANY dropdown in my application. All I need to do is pass a query and the dropdown. So if I remove my comments, then almost with the same number of line that I take to bind one single dropdown using <asp:SqlDataSource> I can Bind All dropdowns in my application. The function GetCounrtyList can further be modified to be a common function with the help of Enum and a Database driven Query! So practically with just 10 lines of code and one Sql table (which will have all my SQL Queries to bind dropdowns (or even better, any data driven control) across my application and a enum to be passed from the .cs page (which is specific to that control/query) I can complete the whole story of DropDown Binding.
Please think about the amount of flexibility, code reuse, modularity this second approach provides.
So Is <asp:SqlDataSource> is a Bad Bad Devil?
Not necessary. It has its own uses, when we want to bind a grid with paging, sorting, etc – this is one of the best options – we do not need to write 100s of lines of code to achieve that. But the point here is we need to think, debate, ask, read, be certain before we use something for some purpose. Else, be ready to change 50 pages when a single “ORDER BY” clause needs a change in the Query!
Happy Programming!