Monday, 8 October 2012

Perfect Message For Boyfriend and Girlfriend















  •  Our love is like a rose, blooming in spring. It keeps growing as time passes. It is everlasting like the sun. I cannot exist without you. I love you so much.

  • Love is like a beautiful garden. It brings zest and enthusiasm into our lives. It fills our lives with bliss. Life without love feels incomplete. I am so lucky to be in love. I love you my sweetheart. To me, you are no less than a dream come true. I love you so much.

  • You are no less than a blessing in disguise to me. I cherish every second I spend with you. I find myself loving you more everyday. You are the reason I am, I love you.

  • As each day passes, you just keep coming closer to my heart. May the trust and understanding that we share among us grow with each passing day. I love you.

  • I just cannot stop thinking about you. You make my world so beautiful. You are perfect, just the way you are.

  • You are the most amazing person I have ever met. You make the world a better place to live in. I feel so lucky to be loved by someone like you.

  • You are the most beautiful dream I'm living. You are everything I would ever want and ever need. I love you. 

  • I will do whatever it takes to keep you happy. I promise to love you till eternity. I love you truly, madly, deeply...forever

  • If I had just one kiss to give, I'd save it for you. You mean a lot to me sweetie.

  • I wrote your name on the sand and the ocean washed it away. I've written your name on my heart and I know forever it will stay.

  • When I think of you, I smile. When I smile, I think of you. You are my happiness and my every happiness comes from you. I love you.

  • You are the girl with the sunshine smile. Your voice is like a ray of hope. You fill my life with all the rainbow colors. Girl, to me you are no less than an angel from heaven. I love you.

  • You are the girl of every guy's dreams. I am so lucky that you belong to me. I love you dear.

  • Hey sweetie, you are the special someone who was missing in my life. I'm so addicted to you. I love you.

  • Love is the most beautiful feeling in the world. I'm so glad I got to experience it because of you. I love you.

  • Was just dropping by your inbox to remind you, that you are the one who is always on my mind. I love you.

  • Hey baby doll, you mean the world to me. Your cute smile make me feel alive. I love you.

  • You are the cutest girl I have seen all my life. I'm in love with you.

  • You are the best girlfriend I could have ever asked God for. I love you so much my dear.

  • You being my girlfriend is the next best thing that has ever happened to me because, finding you from among millions is the best! Now that I have finally found you, I don't ever want to lose you again.

  • You are just not a pretty face, you have an even more beautiful heart. You are my princess and I will always love you.

  • Me, you and our love is all it takes to make the perfect world in which I want to live forever. I love you darling.

  • You are a certified rock star because you rock my world with your beauty, charm, sexiness and a warm and caring attitude. I love you!

  • If you asked me to wait for you, I'd wait until death. Because death in hope is better than a death with a broken heart. Be mine forever sweetheart because I promise to love you forever.

  • Love has its ups and downs. But I'm never sad for more than a minute because the thought of having you in my life always brings a big smile on my face. I love you sweetheart.

  • Success, happiness, wealth and health mean nothing without having you around to share it. I just want to say I love you to the most important part of my life – You!

  • I don't need to look around or ask God for miracles, because you are the miracle in my life. I love you!

  • I spent many days and months just dreaming of having you as my girlfriend. Now that I have you, I think I am living a dream that I never want to come out of. You make life seem like a celebration every day sweetheart. I love you.

  • If my life is a garden, you are the only rose in it.

  • Whoever said that nothing lasts forever, has definitely not seen my undying love for you. It is the only thing that will go on until time ends. I love you.

  • I feel like the luckiest guy in the whole world to have a beautiful, sexy and honest girlfriend like you. I hope my luck never runs out and I can make you mine forever. I love you.

  • The best thing I've done in my life is love you
           The best gift I've received in my life is your love
          And the best thing that has ever happened to me is you
          I love you

  • If a genie popped up and asked me for anything in the world, I would tell him that I already have everything I need in the world – You!

  • You are the missing piece in the puzzle and jigsaw of my life. Darling, you make my life complete in every way. I love you.

  • If you ever happen to see a shooting star, wish for all my wishes to come true. Because all I wish to do in life is to keep you happy.

  • I never knew life could be so beautiful until I met you. I love you.

  • If I die I want to become a star so that I can shine my love for you from the heavens above. I love you and only you, now and forever!

  • The shortest definition of happiness is YOU
          The shortest definition of love is YOU
          The shortest definition of togetherness is YOU
          The shortest definition of my life is YOU
          I love you

  • Every second spent with you seems like an eternity full of smiles, happiness and love. I can't even imagine how heavenly and blissful it would be to spend my whole life with you.

  • If I had nothing else to do, I'd take a sleeping bag, find my comfy spot inside your heart and camp there forever and ever!

  • I wish I could pluck the stars and gift you one every single day. And then, I could truly call you the sky princess! Stay beautiful, my girl. You're the best.   

Monday, 11 June 2012

AdoDotNet/Lesson07


Lesson 07

The C# Station ADO.NET Tutorial

by Joe Mayo, 9/12/04

Lesson 07: Using Stored Procedures

This lesson shows how to use stored procedures in your data access code. Here are the objectives of this lesson:

  • Learn how to modify the SqlCommand object to use a stored procedure.
  • Understand how to use parameters with stored procedures.

Introduction

A stored procedures is a pre-defined, reusable routine that is stored in a database. SQL Server compiles stored procedures, which makes them more efficient to use. Therefore, rather than dynamically building queries in your code, you can take advantage of the reuse and performance benefits of stored procedures. The following sections will show you how to modify the SqlCommand object to use stored procedures. Additionally, you'll see another reason why parameter support is an important part of the ADO.NET libraries.

Executing a Stored Procedure

In addition to commands built with strings, the SqlCommand type can be used to execute stored procedures. There are two tasks require to make this happen: let the SqlCommand object know which stored procedure to execute and tell the SqlCommand object that it is executing a stored procedure. These two steps are shown below:

 // 1. create a command object identifying
 // the stored procedure
 SqlCommand cmd  = new SqlCommand(
  "Ten Most Expensive Products", conn);

 // 2. set the command object so it knows
 // to execute a stored procedure
 cmd.CommandType = CommandType.StoredProcedure;

While declaring the SqlCommand object above, the first parameter is set to "Ten Most Expensive Products". This is the name of a stored procedure in the Northwind database. The second parameter is the connection object, which is the same as the SqlCommand constructor used for executing query strings.

The second command tells the SqlCommand object what type of command it will execute by setting its CommandType property to the StoredProcedure value of the CommandType enum. The default interpretation of the first parameter to the SqlCommand constructor is to treat it as a query string. By setting the CommandType to StoredProcedure, the first parameter to the SqlCommand constructor will be interpreted as the name of a stored procedure (instead of interpreting it as a command string). The rest of the code can use the SqlCommand object the same as it is used in previous lessons.

Sending Parameters to Stored Procedures

Using parameters for stored procedures is the same as using parameters for query string commands. The following code shows this:

 // 1. create a command object identifying
 // the stored procedure
 SqlCommand cmd  = new SqlCommand(
  "CustOrderHist", conn);

 // 2. set the command object so it knows
 // to execute a stored procedure
 cmd.CommandType = CommandType.StoredProcedure;

 // 3. add parameter to command, which
 // will be passed to the stored procedure
 cmd.Parameters.Add(
  new SqlParameter("@CustomerID", custId));

The SqlCommand constructor above specifies the name of a stored procedure, CustOrderHist, as its first parameter. This particular stored procedure takes a single parameter, named @CustomerID. Therefore, we must populate this parameter using a SqlParameter object. The name of the parameter passed as the first parameter to the SqlParameter constructor must be spelled exactly the same as the stored procedure parameter. Then execute the command the same as you would with any other SqlCommand object.

A Full Example

The code in Listing 1 contains a full working example of how to use stored procedures. There are separate methods for a stored procedure without parameters and a stored procedure with parameters.

Listing 1: Executing Stored Procedures
using System;
using System.Data;
using System.Data.SqlClient;

class StoredProcDemo
{
 static void Main()
 {
  StoredProcDemo spd = new StoredProcDemo();

  // run a simple stored procedure
  spd.RunStoredProc();

  // run a stored procedure that takes a parameter
  spd.RunStoredProcParams();
 }

 // run a simple stored procedure
 public void RunStoredProc()
 {
  SqlConnection conn = null;
  SqlDataReader rdr  = null;

  Console.WriteLine("\nTop 10 Most Expensive Products:\n");

  try
  {
   // create and open a connection object
   conn = new 
    SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
   conn.Open();

   // 1. create a command object identifying
   // the stored procedure
   SqlCommand cmd  = new SqlCommand(
    "Ten Most Expensive Products", conn);

   // 2. set the command object so it knows
   // to execute a stored procedure
   cmd.CommandType = CommandType.StoredProcedure;

   // execute the command
   rdr = cmd.ExecuteReader();

   // iterate through results, printing each to console
   while (rdr.Read())
   {
    Console.WriteLine(
     "Product: {0,-25} Price: ${1,6:####.00}",
     rdr["TenMostExpensiveProducts"],
     rdr["UnitPrice"]);
   }
  }
  finally
  {
   if (conn != null)
   {
    conn.Close();
   }
   if (rdr != null)
   {
    rdr.Close();
   }
  }
 }

 // run a stored procedure that takes a parameter
 public void RunStoredProcParams()
 {
  SqlConnection conn = null;
  SqlDataReader rdr  = null;

  // typically obtained from user
  // input, but we take a short cut
  string custId = "FURIB";

  Console.WriteLine("\nCustomer Order History:\n");

  try
  {
   // create and open a connection object
   conn = new 
    SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI");
   conn.Open();

   // 1. create a command object identifying
   // the stored procedure
   SqlCommand cmd  = new SqlCommand(
    "CustOrderHist", conn);

   // 2. set the command object so it knows
   // to execute a stored procedure
   cmd.CommandType = CommandType.StoredProcedure;

   // 3. add parameter to command, which
   // will be passed to the stored procedure
   cmd.Parameters.Add(
    new SqlParameter("@CustomerID", custId));

   // execute the command
   rdr = cmd.ExecuteReader();

   // iterate through results, printing each to console
   while (rdr.Read())
   {
    Console.WriteLine(
     "Product: {0,-35} Total: {1,2}",
     rdr["ProductName"],
     rdr["Total"]);
   }
  }
  finally
  {
   if (conn != null)
   {
    conn.Close();
   }
   if (rdr != null)
   {
    rdr.Close();
   }
  } 
 }
}

The RunStoredProc method in Listing 1 simply runs a stored procedure and prints the results to the console. In the RunStoredProcParams method, the stored procedure used takes a single parameter. This demonstrates that there is no difference between using parameters with query strings and stored procedures. The rest of the code should be familiar to those who have read previous lessons in this tutorial.

Summary

To execute stored procedures, you specify the name of the stored procedure in the first parameter of a SqlCommand constructor and then set the CommandType of the SqlCommand to StoredProcedure. You can also send parameters to a stored procedure by using SqlParameter objects, the same way it is done with SqlCommand objects that execute query strings. Once the SqlCommand object is constructed, you can use it just like any other SqlCommand object as described in previous lessons.

Your feedback and constructive contributions are welcome. Please feel free to contact me for feedback or comments you may have about this article.

Feedback

Sponsored by: LinqLing - Be Disruptive!

Copyright © 2000 - 2012 C# Station, All Rights Reserved

AdoDotNet/Lesson06


Lesson 06

The C# Station ADO.NET Tutorial

by Joe Mayo, 9/5/04

Lesson 06: Adding Parameters to Commands

This lesson shows you how to use parameters in your commands.2 Here are the objectives of this lesson:

  • Understand what a parameter is.
  • Be informed about the benefits of using parameters.
  • Learn how to create a parameter.
  • Learn how to assign parameters to commands.

Introduction

When working with data, you'll often want to filter results based on some criteria. Typically, this is done by accepting input from a user and using that input to form a SQL query. For example, a sales person may need to see all orders between specific dates. Another query might be to filter customers by city.

As you know, the SQL query assigned to a SqlCommand object is simply a string. So, if you want to filter a query, you could build the string dynamically, but you wouldn't want to. Here is a bad example of filtering a query.

 // don't ever do this
 SqlCommand cmd = new SqlCommand(
  "select * from Customers where city = '" + inputCity + "'";

Don't ever build a query this way! The input variable, inputCity, is typically retrieved from a TextBox control on either a Windows form or a Web Page. Anything placed into that TextBox control will be put into inputCity and added to your SQL string. This situation invites a hacker to replace that string with something malicious. In the worst case, you could give full control of your computer away.

Instead of dynamically building a string, as shown in the bad example above, use parameters. Anything placed into a parameter will be treated as field data, not part of the SQL statement, which makes your application much more secure.

Using parameterized queries is a three step process:

  1. Construct the SqlCommand command string with parameters.
  2. Declare a SqlParameter object, assigning values as appropriate.
  3. Assign the SqlParameter object to the SqlCommand object's Parameters property.

The following sections take you step-by-step through this process.

preparing a SqlCommand Object for Parameters

The first step in using parameters in SQL queries is to build a command string containing parameter placeholders. These placeholders are filled in with actual parameter values when the SqlCommand executes. Proper syntax of a parameter is to use an '@' symbol prefix on the parameter name as shown below:

 // 1. declare command object with parameter
 SqlCommand cmd = new SqlCommand(
  "select * from Customers where city = @City", conn);

In the SqlCommand constructor above, the first argument contains a parameter declaration, @City. This example used one parameter, but you can have as many parameters as needed to customize the query. Each parameter will match a SqlParameter object that must be assigned to this SqlCommand object.

Declaring a SqlParameter Object

Each parameter in a SQL statement must be defined. This is the purpose of the SqlParameter type. Your code must define a SqlParameter instance for each parameter in a SqlCommand object's SQL command. The following code defines a parameter for the @City parameter from the previous section:

 // 2. define parameters used in command object
 SqlParameter param  = new SqlParameter();
 param.ParameterName = "@City";
 param.Value         = inputCity;

Notice that the ParameterName property of the SqlParameter instance must be spelled exactly as the parameter that is used in the SqlCommand SQL command string. You must also specify a value for the command. When the SqlCommand object executes, the parameter will be replaced with this value.

Associate a SqlParameter Object with a SqlCommand Object

For each parameter defined in the SQL command string argument to a SqlCommand object, you must define a SqlParameter. You must also let the SqlCommand object know about the SqlParameter by assigning the SqlParameter instance to the Parameters property of the SqlCommand object. The following code shows how to do this:

 // 3. add new parameter to command object
 cmd.Parameters.Add(param);

The SqlParameter instance is the argument to the Add method of the Parameters property for the SqlCommand object above. You must add a unique SqlParameter for each parameter defined in the SqlCommand object's SQL command string.

Putting it All Together

You already know how to use SqlCommand and SqlDataReader objects. The following code demonstrates a working program that uses SqlParameter objects. So, everything should be familiar by now, except for the new parts presented in this article:

Listing 1: Adding Parameters to Queries
using System;
using System.Data;
using System.Data.SqlClient;

class ParamDemo
{
 static void Main()
 {
  // conn and reader declared outside try
  // block for visibility in finally block
  SqlConnection conn   = null;
  SqlDataReader reader = null;

  string inputCity = "London";
try { // instantiate and open connection conn = new SqlConnection("Server=(local);DataBase=Northwind;Integrated Security=SSPI"); conn.Open(); // don't ever do this // SqlCommand cmd = new SqlCommand( // "select * from Customers where city = '" + inputCity + "'"; // 1. declare command object with parameter SqlCommand cmd = new SqlCommand( "select * from Customers where city = @City", conn); // 2. define parameters used in command object SqlParameter param = new SqlParameter(); param.ParameterName = "@City"; param.Value = inputCity; // 3. add new parameter to command object cmd.Parameters.Add(param); // get data stream reader = cmd.ExecuteReader(); // write each record while(reader.Read()) { Console.WriteLine("{0}, {1}", reader["CompanyName"], reader["ContactName"]); } } finally { // close reader if (reader != null) { reader.Close(); } // close connection if (conn != null) { conn.Close(); } } } }

The code in Listing 1 retrieves records for each customer that lives in London. This was made more secure through the use of parameters. Besides using parameters, all of the other code contains techniques you've learned in previous lessons.

Summary

You should use parameters to filter queries in a secure manner. The process of using parameter contains three steps: define the parameter in the SqlCommand command string, declare the SqlParameter object with applicable properties, and assign the SqlParameter object to the SqlCommand object. When the SqlCommand executes, parameters will be replaced with values specified by the SqlParameter object.

I hope you enjoyed this lesson and welcome you to return to the next one in this series, Lesson 07: Using Stored Procedures.

Your feedback and constructive contributions are welcome. Please feel free to contact me for feedback or comments you may have about this article.

Feedback

Sponsored by: LinqLing - Be Disruptive!

Copyright © 2000 - 2012 C# Station, All Rights Reserved

AdoDotNet/Lesson05


Lesson 05

The C# Station ADO.NET Tutorial

by Joe Mayo, 8/30/04, updated 1/12/09

Lesson 05: Working with Disconnected Data - The DataSet and SqlDataAdapter

This lesson explains how to work with disconnected data, using the DataSet and SqlDataAdapter objects. Here are the objectives of this lesson:

  • Understand the need for disconnected data.
  • Obtain a basic understanding of what a DataSet is for.
  • Learn to use a SqlDataAdapter to retrieve and update data.

Introduction

In Lesson 3, we discussed a fully connected mode of operation for interacting with a data source by using the SqlCommand object. In Lesson 4, we learned about how to read data quickly an let go of the connection with the SqlDataReader. This Lesson shows how to accomplish something in-between SqlConnection and SqlDataReader interaction by using the DataSet and SqlDataAdapter objects.

A DataSet is an in-memory data store that can hold numerous tables. DataSets only hold data and do not interact with a data source. It is the SqlDataAdapter that manages connections with the data source and gives us disconnected behavior. The SqlDataAdapter opens a connection only when required and closes it as soon as it has performed its task. For example, the SqlDataAdapter performs the following tasks when filling a DataSet with data:

  1. Open connection
  2. Retrieve data into DataSet
  3. Close connection

and performs the following actions when updating data source with DataSet changes:

  1. Open connection
  2. Write changes from DataSet to data source
  3. Close connection

In between the Fill and Update operations, data source connections are closed and you are free to read and write data with the DataSet as you need. These are the mechanics of working with disconnected data. Because the applications holds on to connections only when necessary, the application becomes more scalable.

A couple scenarios illustrate why you would want to work with disconnected data: people working without network connectivity and making Web sites more scalable. Consider sales people who need customer data as they travel. At the beginning of the day, they'll need to sync up with the main database to have the latest information available. During the day, they'll make modifications to existing customer data, add new customers, and input new orders. This is okay because they have a given region or customer base where other people won't be changing the same records. At the end of the day, the sales person will connect to the network and update changes for overnight processing.

Another scenario is making a Web site more scalable. With a SqlDataReader, you have to go back to the database for records every time you show a page. This requires a new connection for each page load, which will hurt scalability as the number of users increase. One way to relieve this is to use a DataSet that is updated one time and stored in cache. Every request for the page checks the cache and loads the data if it isn't there or just pulls the data out of cache and displays it. This avoids a trip to the database, making your application more efficient.

Exceptions to the scenario above include situations where you need to update data. You then have to make a decision, based on the nature of how the data will be used as to your strategy. Use disconnected data when your information is primarily read only, but consider other alternatives (such as using SqlCommand object for immediate update) when your requirements call for something more dynamic. Also, if the amount of data is so large that holding it in memory is impractical, you will need to use SqlDataReader for read-only data. Really, one could come up with all kinds of exceptions, but the true guiding force should be the requirements of your application which will influence what your design should be.

Creating a DataSet Object

There isn't anything special about instantiating a DataSet. You just create a new instance, just like any other object:

DataSet dsCustomers = new DataSet();

The DataSet constructor doesn't require parameters. However there is one overload that accepts a string for the name of the DataSet, which is used if you were to serialize the data to XML. Since that isn't a requirement for this example, I left it out. Right now, the DataSet is empty and you need a SqlDataAdapter to load it.

Creating A SqlDataAdapter

The SqlDataAdapter holds the SQL commands and connection object for reading and writing data. You initialize it with a SQL select statement and connection object:

SqlDataAdapter daCustomers = new SqlDataAdapter(
    "select CustomerID, CompanyName from Customers", conn);

The code above creates a new SqlDataAdapter, daCustomers. The SQL select statement specifies what data will be read into a DataSet. The connection object, conn, should have already been instantiated, but not opened. It is the SqlDataAdapter's responsibility to open and close the connection during Fill and Update method calls.

As indicated earlier, the SqlDataAdapter contains all of the commands necessary to interact with the data source. The code showed how to specify the select statment, but didn't show the insert, update, and delete statements. These are added to the SqlDataAdapter after it is instantiated.

There are two ways to add insert, update, and delete commands: via SqlDataAdapter properties or with a SqlCommandBuilder. In this lesson, I'm going to show you the easy way of doing it with the SqlCommandBuilder. In a later lesson, I'll show you how to use the SqlDataAdapter properties, which takes more work but will give you more capabilities than what the SqlCommandBuilder does. Here's how to add commands to the SqlDataAdapter with the SqlCommandBuilder:

SqlCommandBuilder cmdBldr = new SqlCommandBuilder(daCustomers);

Notice in the code above that the SqlCommandBuilder is instantiated with a single constructor parameter of the SqlDataAdapter, daCustomers, instance. This tells the SqlCommandBuilder what SqlDataAdapter to add commands to. The SqlCommandBuilder will read the SQL select statement (specified when the SqlDataAdapter was instantiated), infer the insert, update, and delete commands, and assign the new commands to the Insert, Update, and Delete properties of the SqlDataAdapter, respectively.

As I mentioned earlier, the SqlCommandBuilder has limitations. It works when you do a simple select statement on a single table. However, when you need a join of two or mor tables or must do a stored procedure, it won't work. I'll describe a work-around for these scenarios in future lessons.

Filling the DataSet

Once you have a DataSet and SqlDataAdapter instances, you need to fill the DataSet. Here's how to do it, by using the Fill method of the SqlDataAdapter:

daCustomers.Fill(dsCustomers, "Customers");

The Fill method, in the code above, takes two parameters: a DataSet and a table name. The DataSet must be instantiated before trying to fill it with data. The second parameter is the name of the table that will be created in the DataSet. You can name the table anything you want. Its purpose is so you can identify the table with a meaningful name later on. Typically, I'll give it the same name as the database table. However, if the SqlDataAdapter's select command contains a join, you'll need to find another meaningful name.

The Fill method has an overload that accepts one parameter for the DataSet only. In that case, the table created has a default name of "table1" for the first table. The number will be incremented (table2, table3, ..., tableN) for each table added to the DataSet where the table name was not specified in the Fill method.

Using the DataSet

A DataSet will bind with both ASP.NET and Windows forms DataGrids. Here's an example that assigns the DataSet to a Windows forms DataGrid:

dgCustomers.DataSource = dsCustomers;
dgCustomers.DataMember = "Customers";

The first thing we do, in the code above, is assign the DataSet to the DataSource property of the DataGrid. This lets the DataGrid know that it has something to bind to, but you will get a '+' sign in the GUI because the DataSet can hold multiple tables and this would allow you to expand each available table. To specify exactly which table to use, set the DataGrid's DataMember property to the name of the table. In the example, we set the name to Customers, which is the same name used as the second parameter to the SqlDataAdapter Fill method. This is why I like to give the table a name in the Fill method, as it makes subsequent code more readable.

Updating Changes

After modifications are made to the data, you'll want to write the changes back to the database. Refer to previous discussion in the Introduction of this article on update guidance. The following code shows how to use the Update method of the SqlDataAdapter to push modifications back to the database.

daCustomers.Update(dsCustomers, "Customers");

The Update method, above, is called on the SqlDataAdapter instance that originally filled the dsCustomers DataSet. The second parameter to the Update method specifies which table, from the DataSet, to update. The table contains a list of records that have been modified and the Insert, Update, and Delete properties of the SqlDataAdapter contain the SQL statements used to make database modifications.

Putting it All Together

Until now, you've seen the pieces required to implement disconnected data managment. What you really need is to see all this implemented in an application. Listing 1 shows how the code from all the previous sections is used in a working program that has been simplified to enhance the points of this lesson:

Listing 1: Implementing a Disconnected Data Management Strategy
using System;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Windows.Forms;

class DisconnectedDataform : Form
{
 private SqlConnection  conn;
 private SqlDataAdapter daCustomers;

 private DataSet  dsCustomers;
 private DataGrid dgCustomers;

 private const string tableName = "Customers";

 // initialize form with DataGrid and Button
 public DisconnectedDataform()
 {
  // fill dataset
  Initdata();

  // set up datagrid
  dgCustomers = new DataGrid();
  dgCustomers.Location = new Point(5, 5);
  dgCustomers.Size = new Size(  
            this.ClientRectangle.Size.Width - 10,  
            this.ClientRectangle.Height - 50);
  dgCustomers.DataSource = dsCustomers;
  dgCustomers.DataMember = tableName;

  // create update button
  Button btnUpdate = new Button();
  btnUpdate.Text = "Update";
  btnUpdate.Location = new Point(
   this.ClientRectangle.Width/2 - btnUpdate.Width/2,
   this.ClientRectangle.Height - (btnUpdate.Height + 10));
  btnUpdate.Click += new EventHandler(btnUpdateClicked);

  // make sure controls appear on form
  Controls.AddRange(new Control[] { dgCustomers, btnUpdate });
 }

 // set up ADO.NET objects
 public void Initdata()
 {
  // instantiate the connection
  conn = new SqlConnection(
"Server=(local);DataBase=Northwind;Integrated Security=SSPI"); // 1. instantiate a new DataSet dsCustomers = new DataSet(); // 2. init SqlDataAdapter with select command and connection daCustomers = new SqlDataAdapter(
"select CustomerID, CompanyName from Customers", conn); // 3. fill in insert, update, and delete commands SqlCommandBuilder cmdBldr = new SqlCommandBuilder(daCustomers); // 4. fill the dataset daCustomers.Fill(dsCustomers, tableName); } // Update button was clicked public void btnUpdateClicked(object sender, EventArgs e) { // write changes back to DataBase daCustomers.Update(dsCustomers, tableName); } // start the Windows form static void Main() { Application.Run(new DisconnectedDataForm()); } }

The Initdata method in Listing 1 contains the methods necessary to set up the SqlDataAdapter and DataSet. Notice that various data objects are defined at class level so they can be used in multiple methods. The DataGrid's DataSource property is set in the constructor. Whenever a user clicks the Update button, the Update method in the btnUpdateClicked event handler is called, pushing modifications back to the database.

Summary

DataSets hold multiple tables and can be kept in memory and reused. The SqlDataAdapter enables you to fill a DataSet and Update changes back to the database. You don't have to worry about opening and closing the SqlConnection because the SqlDataAdapter does it automatically. A SqlCommandBuilder populates insert, update, and delete commands based on the SqlDataAdapter's select statement. Use the Fill method of the SqlDataAdapter to fill a DataSet with data. Call the SqlDataAdapter's Update method to push changes back to a database.

I hope you enjoyed this lesson and welcome you to return to the next one in this series, Lesson 06: Adding Parameters to Commands.

Your feedback and constructive contributions are welcome. Please feel free to contact me for feedback or comments you may have about this article.

Feedback

Sponsored by: LinqLing - Be Disruptive!

Copyright © 2000 - 2012 C# Station, All Rights Reserved

AdoDotNet/Lesson04


Lesson 04

The C# Station ADO.NET Tutorial

by Joe Mayo, 8/25/04

Lesson 04: Reading Data with the SqlDataReader

This lesson explains how to read data with a SqlDataReader object. Here are the objectives of this lesson:

  • Learn what a SqlDataReader is used for.
  • Know how to read data using a SqlDataReader.
  • Understand the need to close a SqlDataReader.

Introduction

A SqlDataReader is a type that is good for reading data in the most efficient manner possible. You can *not* use it for writing data. SqlDataReaders are often described as fast-forward firehose-like streams of data.

You can read from SqlDataReader objects in a forward-only sequential manner. Once you've read some data, you must save it because you will not be able to go back and read it again.

The forward only design of the SqlDataReader is what enables it to be fast. It doesn't have overhead associated with traversing the data or writing it back to the data source. Therefore, if your only requirement for a group of data is for reading one time and you want the fastest method possible, the SqlDataReader is the best choice. Also, if the amount of data you need to read is larger than what you would prefer to hold in memory beyond a single call, then the streaming behavior of the SqlDataReader would be a good choice.

Note: Observe that I used the term "one time" in the previous paragraph when discussing the reasons why you would use a SqlDataReader. As with anything, there are exceptions. In many cases, it is more efficient to use a cached DataSet. While caching is outside the scope of this tutorial, we will discuss using DataSet objects in the next lesson.

Creating a SqlDataReader Object

Getting an instance of a SqlDataReader is a little different than the way you instantiate other ADO.NET objects. You must call ExecuteReader on a command object, like this:

    SqlDataReader rdr = cmd.ExecuteReader();

The ExecuteReader method of the SqlCommand object, cmd , returns a SqlDataReader instance. Creating a SqlDataReader with the new operator doesn't do anything for you. As you learned in previous lessons, the SqlCommand object references the connection and the SQL statement necessary for the SqlDataReader to obtain data.

Reading Data

previous lessons contained code that used a SqlDataReader, but the discussion was delayed so we could focus on the specific subject of that particular lesson. This lesson builds from what you've seen and explains how to use the SqlDataReader.

As explained earlier, the SqlDataReader returns data via a sequential stream. To read this data, you must pull data from a table row-by-row Once a row has been read, the previous row is no longer available. To read that row again, you would have to create a new instance of the SqlDataReader and read through the data stream again.

The typical method of reading from the data stream returned by the SqlDataReader is to iterate through each row with a while loop. The following code shows how to accomplish this:

 while (rdr.Read())
 {
  // get the results of each column
  string contact = (string)rdr["ContactName"];
  string company = (string)rdr["CompanyName"];
  string city    = (string)rdr["City"];

  // print out the results
  Console.Write("{0,-25}", contact);
  Console.Write("{0,-20}", city);
  Console.Write("{0,-25}", company);
  Console.WriteLine();
 }

Notice the call to Read on the SqlDataReader, rdr, in the while loop condition in the code above. The return value of Read is type bool and returns true as long as there are more records to read. After the last record in the data stream has been read, Read returns false.

In previous lessons, we extracted the first column from the row by using the SqlDataReader indexer, i.e. rdr[0]. You can extract each column of the row with a numeric indexer like this, but it isn't very readable. The example above uses a string indexer, where the string is the column name from the SQL query (the table column name if you used an asterisk, *. String indexers are much more readable, making the code easier to maintain.

Regardless of the type of the indexer parameter, a SqlDataReader indexer will return type object. This is why the example above casts results to a string. Once the values are extracted, you can do whatever you want with them, such as printing them to output with Console type methods.

Finishing Up

Always remember to close your SqlDataReader, just like you need to close the SqlConnection. Wrap the data access code in a try block and put the close operation in the finally block, like this:

 try
 {
  // data access code
 }
 finally
 {
  // 3. close the reader
  if (rdr != null)
  {
   rdr.Close();
  }

  // close the connection too
 } 

The code above checks the SqlDataReader to make sure it isn't null. After the code knows that a good instance of the SqlDataReader exists,it can close it. Listing 1 shows the code for the previous sections in its entirety.

Listing 1: Using the SqlDataReader
using System;
using System.Data;
using System.Data.SqlClient;

namespace Lesson04
{
 class ReaderDemo
 {
  static void Main()
  {
   ReaderDemo rd = new ReaderDemo();
   rd.SimpleRead();
  }

  public void SimpleRead()
  {
   // declare the SqlDataReader, which is used in
   // both the try block and the finally block
   SqlDataReader rdr = null;

   // create a connection object
   SqlConnection conn = new SqlConnection(
"Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI");

   // create a command object
   SqlCommand cmd  = new SqlCommand(
    "select * from Customers", conn);

   try
   {
    // open the connection
    conn.Open();

    // 1. get an instance of the SqlDataReader
    rdr = cmd.ExecuteReader();

    // print a set of column headers
    Console.WriteLine(
"Contact Name             City                Company Name");
    Console.WriteLine(
"------------             ------------        ------------");

    // 2. print necessary columns of each
                    record
    while (rdr.Read())
    {
     // get the results of each column
     string contact = (string)rdr["ContactName"];
     string company = (string)rdr["CompanyName"];
     string city    = (string)rdr["City"];

     // print out the results
     Console.Write("{0,-25}", contact);
     Console.Write("{0,-20}", city);
     Console.Write("{0,-25}", company);
     Console.WriteLine();
    }
   }
   finally
   {
    // 3. close the reader
    if (rdr != null)
    {
     rdr.Close();
    }

    // close the connection
    if (conn != null)
    {
     conn.Close();
    }
   } 
  }
 }
}

Summary

SqlDataReader objects allow you to read data in a fast forward-only manner. You obtain data by reading each row from the data stream. Call the Close method of the SqlDataReader to ensure there are not any resource leaks.

I hope you enjoyed this lesson. The next one in this series is Lesson 05: Working with Disconnected Data - The DataSet and SqlDataAdapter

Your feedback and constructive contributions are welcome. Please feel free to contact me for feedback or comments you may have about this article.

Feedback

Sponsored by: LinqLing - Be Disruptive!

Copyright © 2000 - 2012 C# Station, All Rights Reserved