Sunday, June 3, 2012

WinRT - An Introduction

With imminent release of Windows 8, the buzzword has been Metro UI and Metro based applications. With Windows 8, Microsoft is introducing a new development platform called WinRT or Windows Runtime, that has developer community scratching its head.

Over 10 years ago Microsoft introduced the .NET framework which revolutionized Web Development at least for Microsoft developers. Those of us that were developing web based applications in classic ASP exhaled a sigh of relief. As framework matured, Visual Basic and C# matured as well.

Now with WinRT looming, most developers are wondering whether .NET framework is a thing of the past.

Similar to .NET Framework, WinRT is an intermediary and is built on top of COM. It allows you to develop applications using C#, VB.NET, XAML, but also in C++, HTML 5 and Javascript.


Admittedly there are some nice features, such as automatically deciding when to execute code in asynchronous mode rather than relying on developers, there are also some serious constraints - for example applications developed in WinRT will not run on previous versions of windows.

If you are wondering why another framework, why not just enhance .NET Framework to work with Metro apps? I am sure you are not alone.

Thank you.

Saturday, May 19, 2012

Linq to Objects

In previous couple of posts we looked at the Linq to SQL i.e. using data context to get data from the database into an object collection. Today, we will look into using this object collection to filter data based on a certain criteria using Linq. If you haven't already figured it out, Linq is very similar to SQL except that the condition statements such as SELECT, WHERE etc. are reversed. Another requirement is that you must use aliases when writing Linq queries.

Let's look at an example. In this example, I am creating a customer class and creating a collection object (I have hard-coded values here, but in reality you will populate it from the database or other sources).

Once I have created an object collection, I can write Linq queries to filter the data. In this example, we are selecting all customers, filtering customers whose last name ends with a specific character and also ordering all customers by their last name. If you have more than one collection, you can create joins. In essence, you can write queries that are similar to T-SQL but they work on objects.

Main()

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqToObject
{
    class Program
    {
        static void Main(string[] args)
        {
            //create a collection and call a method to populate this collection
            List<Customer> customerList = new List<Customer>();
            Customer cust = new Customer();
            customerList = cust.createCollection();

            //Now I have a collection called customerList of type Customer. 
            // Let's use Linq to get results from this collection

            // Select all customers
            SelectAllCustomers(customerList);

            Console.WriteLine(Environment.NewLine);
            Console.WriteLine(Environment.NewLine);

            //Select all customers Ordered by LastName Desc.
            SelectAllCustomersOrdered(customerList);

            Console.WriteLine(Environment.NewLine);
            Console.WriteLine(Environment.NewLine);
                
            //Select a specific customer
            SelectOneCustomer(customerList);
            
            Console.Read();

        }
        static void SelectAllCustomers(List<Customer> customerList)
        {
            var customers = from d in customerList
                            select d;
            foreach (var cust in customers)
            {
                Console.WriteLine("{0}, {1}, {2}", 
                    cust.FirstName + " " + cust.LastName,cust.Email,
                    cust.StreetAddress + ", " + cust.City + ", " + 
                    cust.State + ", " + cust.ZipCode);
            }
        }
        static void SelectAllCustomersOrdered(List<Customer> customerList)
        {
            var customers = from d in customerList
                            orderby d.LastName descending
                            select d;
            foreach (var cust in customers)
            {
                Console.WriteLine("{0}, {1}, {2}",
                    cust.FirstName + " " + cust.LastName, cust.Email, 
                    cust.StreetAddress + ", " + cust.City + ", " + 
                    cust.State + ", " + cust.ZipCode);
            }
        }
        static void SelectOneCustomer(List<Customer> customerList)
        {
            var customers = from d in customerList
                            where d.FirstName.EndsWith("0")
                            select d;
            foreach (var cust in customers)
            {
                Console.WriteLine("{0}, {1}, {2}",
                    cust.FirstName + " " + cust.LastName, cust.Email, 
                    cust.StreetAddress + ", " + cust.City + ", " + 
                    cust.State + ", " + cust.ZipCode);
            }
        }
    }
}

Customer Class


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqToObject
{
    class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string StreetAddress { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }

        /// <summary>
        /// Generate a Collection
        /// </summary>
        /// <returns></returns>
        public List<Customer> createCollection()
        {
            List<Customer> custList = new List<Customer>();
            for (int i = 0; i <= 20; i++)
            {
                Customer cust = new Customer();
                cust.FirstName="FN" + i.ToString();
                cust.LastName="LN" + i.ToString();
                cust.Email=cust.FirstName + "." + cust.LastName + "@mail.com";
                cust.StreetAddress = "123" + i.ToString() + " Ross Rd";
                cust.City = "Marietta";
                cust.State = "GA";
                cust.ZipCode = "12345";
                custList.Add(cust);
             }
            return custList;
        }
    }
}

You should try out some other examples using joins etc.

Thank you.

Wednesday, May 16, 2012

Linq to SQL - Part II

In previous post we discussed how you can create DBML file and then use Linq to create SQL like queries to select the data from the database. In this post we will use the same project but see how you can use Linq to update, add and delete a record.

I have created a console app have methods for Select, Update, Add and Delete. Each method uses Linq queries to perform select, update, add and delete functions.

Finally, in Delete method, because my Customers table has a foreign key relationship with Customers_Audit table, I must first delete the record from the Customers_Audit table before deleting from the Customers table.

Let's review an example.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace LinqToSQL
{
    class Program
    {
        static void Main(string[] args)
        {
            // DataContext takes a connection string 
            linqToSQLDataContext db = new linqToSQLDataContext();

            //Select all customers and print them out
            SelectCustomers(db);
            //Update a customer's last name
            UpdateCustomers(db);
            //Add a new customer. 
            //I have a trigger on Customers table which also inserts the new record into 
           //Customers_Audit table
            AddCustomers(db);
            //Delete a Customer
            //Since this table has a foreign key relationship with another table, 
            //I must delete record form both tables
            DeleteCustomer(db);

            Console.Read();

        }
        static void SelectCustomers(linqToSQLDataContext db)
        {
            var customerQuery = from d in db.Customers
                                orderby d.LastName
                                select d;
            foreach (var cust in customerQuery)
            {
                Console.WriteLine("id = {0}, FirstName = {1},LastName = {2}", 
                cust.CustomerID, cust.FirstName, cust.LastName);
            }

            Console.WriteLine(Environment.NewLine);

            //getting data from multiple tables
            var CustomersAndAddresses = from c in db.Customers
                                        from o in db.CustomerAddresses
                                        where c.CustomerID == o.CustomerID
                                        where c.CustomerID == 1
                                        select new { c.FirstName, c.LastName, o.Address1, 
                                                     o.Address2, o.City, o.State };

            foreach (var cust in CustomersAndAddresses)
            {
                Console.WriteLine("Name={0}, Address = {1},City = {2}", 
                cust.FirstName + ' ' + cust.LastName, cust.Address1 + ' ' + 
                cust.Address2, cust.City);
            }
        }
        /// <summary>
        /// Update existing Customers
        /// </summary>
        static void UpdateCustomers(linqToSQLDataContext db)
        {
            var customerQuery = from d in db.Customers
                                orderby d.LastName where d.LastName == "Smith"
                                select d;
            foreach (var cust in customerQuery)
            {
                cust.LastName = "Smithsonian";

            }
            db.SubmitChanges();
            Console.WriteLine("Last Name Updated");
         }
        /// <summary>
        /// Insert new Customers
        /// </summary>
        static void AddCustomers(linqToSQLDataContext db)
        {
            Customer newCustomer = new Customer();

            newCustomer.FirstName="Sonny";
            newCustomer.LastName="Hendrix";
            newCustomer.EmailAddress = "sHendrix@mail.com";
            db.Customers.InsertOnSubmit(newCustomer);
            db.SubmitChanges();
                   
            db.SubmitChanges();
            Console.WriteLine("New Customer Inserted");
        }
        /// <summary>
        /// Delete existing Customer
        /// </summary>
        static void DeleteCustomer(linqToSQLDataContext db)
        {
            var customerAuditQuery = from a in db.Customers_Audits
                                orderby a.LastName
                                where a.LastName == "Hendrix"
                                select a; 
            var customerQuery = from d in db.Customers
                                orderby d.LastName
                                where d.LastName == "Hendrix"
                                select d;
            db.Customers_Audits.DeleteAllOnSubmit(customerAuditQuery);
            db.Customers.DeleteAllOnSubmit(customerQuery);
            db.SubmitChanges();
            Console.WriteLine("Hendrix Deleted");
        }
    }
}

As you can see, it is fairly straightforward and works great for simple applications. It does get rather cumbersome in some cases and doesn't work in others as Linq to SQL only supports 1 to 1 mapping of tables, views etc. Entity framework is more suited for larger, complex applications. To create a DBML file to make your application aware of the underlying database schema, check out my previous post.

Thank you

Thursday, May 10, 2012

Linq To SQL - Part I

In previous few posts we discussed entity framework and how you can use it to model your database tables/views/stored procedures and use them in your application. We also touched on Linq to Entities (more on this later).

Today we will review Linq to SQL. Linq to SQL is another way to work with your database instead of using entity framework. Linq to SQL is good for simple applications as it only supports 1 to 1 mapping of tables, views, procedures or UDFs.

Let's look at an example.

1. I created a console app and added Linq to SQL Classes dbml object.


2. Add the tables  / views you want to generate classes for.



3. Now we will select the data from these tables using Linq to SQL.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace LinqToSQL
{
    class Program
    {
        static void Main(string[] args)
        {
            // DataContext takes a connection string 
            linqToSQLDataContext db = new linqToSQLDataContext();
            
            var customerQuery = from d in db.Customers
                                orderby d.LastName
                                select d;
            foreach (var cust in customerQuery)
            {
                Console.WriteLine("id = {0}, FirstName = {1},LastName = {2}", 
                cust.CustomerID, cust.FirstName, cust.LastName);
            }

            Console.WriteLine(Environment.NewLine);

            //getting data from multiple tables
            var CustomersAndAddresses = from c in db.Customers
                                        from o in db.CustomerAddresses
                                    select new { c.FirstName,c.LastName, 
                                    o.Address1,o.Address2,o.City,o.State };

            foreach (var cust in CustomersAndAddresses)
            {
                Console.WriteLine("Name={0}, Address = {1},City = {2}", 
                cust.FirstName + ' ' + cust.LastName, cust.Address1 + ' ' + 
                cust.Address2, cust.City);
            }
            Console.Read();

        }
    }
}


As you can see in code above, we created two Linq to SQL queries - 1st one is getting data with just one table, the other one with both tables.

You can also add a WHERE clause similar to T-SQL. For example, I can modify above query

var CustomersAndAddresses = from c in db.Customers
                                        from o in db.CustomerAddresses
                                        WHERE c.CustomerID == o.CustomerID
                                       WHERE c.CustomerID == 1
                                        select new { c.FirstName,c.LastName, o.Address1,o.Address2,o.City,o.State };

In next post we will review how you can insert, update or delete a record using Linq to SQL.

Thank you.

Saturday, May 5, 2012

Entity Framework - Using Stored Procedure to Insert/Update/Delete

In previous post, we talked about using SELECT stored procedure with entity framework to get the results. In this post we will discuss how you can use Insert / Update / Delete stored procedures with entity framework. There are two ways to use stored procedures - one with using the object context and calling the stored procedure, passing parameters. Second method is by associating your stored procedures with the entity, which will result in the entity data model automatically calling the stored procedures when you call "SaveChanges" method.

We will look at the same example as before.

1. Open the EDMX file and select the table you want to associate your stored procedures with, right click and select "Stored Procedure Mapping"

2. In the Mapping Details Pane, select the stored procedures for Insert, Update and Delete. Map any columns as necessary, although in most cases your columns should already be mapped appropriately. For Insert, if you are going to return the ID value back, map it to new field.




Note: For the model to work, you must associate all three functions i.e. Insert, Update and Delete.

Now, when you call .SaveChanges() method, any changes made to this table will automatically execute these stored procedures.

Here is the code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
namespace EntiryFramework
{
    public partial class Main2 : Form
    {
        private OrdersEntities orders;
        public Main2()
        {
            InitializeComponent();
        }

        private void Main2_Load(object sender, EventArgs e)
        {
            orders = new OrdersEntities();
            var customerQuery = from d in orders.Customers.Include("CustomerAddresses")
                                orderby d.LastName
                                select d;
            try
            {
                // Bind the ComboBox control to the query, 
                // which is executed during data binding.
                // To prevent the query from being executed multiple times during binding, 
                // it is recommended to bind controls to the result of the Execute method. 
                this.customerList.DisplayMember = "LastName";
                this.customerList.ValueMember = "CustomerID";
                this.customerList.DataSource =
                ((ObjectQuery)customerQuery).Execute(MergeOption.AppendOnly);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        
        private void customerList_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            try
            { //lets get the addresses that are associated with the selected customer
               Customer customer = (Customer)this.customerList.SelectedItem;

                Addresses.DataSource = customer.CustomerAddresses;
                Addresses.Columns["CustomerID"].Visible = false;
                Addresses.Columns["AddressID"].Visible = false;
                Addresses.Columns["Customer"].Visible = false;
                Addresses.AllowUserToDeleteRows = false;
                Addresses.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Close_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void saveChanges_Click(object sender, EventArgs e)
        {
            try
            {

                // Save  changes to the database, 
                // display a message, and refresh the form.
                orders.SaveChanges();
                MessageBox.Show("Changes saved to the database.");
                this.Refresh();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }
    }
}

Thank you.

Thursday, May 3, 2012

Entity Framework - Using Stored Procedures

In previous post we discussed how you can use Entity Framework and use auto generated methods to perform CRUD operations. Although this may work for most simple applications, sometimes you have to have stored procedures either because database doesn't have well defined relationships and constraints or you need data dispersed in multiple tables. Similarly, you may want to use a stored procedure to insert/update multiple tables etc.

While not as straightforward as using EDM provided methods, you can still use stored procedures with entity framework. Today, we will use a SELECT stored procedure to get the results and bind it to our dropdown list just as we did in previous post.

In order to use stored procedures, first you will have to generate functions. As we reviewed in earlier post, when you generate EDM class, wizard gives you an option to select tables / views / stored procedures. Assuming you did, stored procedures are now part of the EDM class.

1. Double click on .edmx file to open it in design surface.
2. Right click anywhere on the surface then Add > Function Import

3. Name your function and select your stored procedure from the drop down.

4. If your stored procedure is not going to return anything (for example, inserting or updating a record) you can select None from Returns a Collection Of (None will return an integer value indicating whether script executed successfully or not). If your stored procedure is going to return a single value, you can select Scalar. But in most cases you will select Complex. If you select Complex you need to click on Get Column Information which will load all the columns returned by the stored procedure. Clicking on Create New Complex Type will create a new object where your stored proc. results will be loaded.

Now your stored procedure is wired up to be used in your code. The code below uses this stored procedure to return a collection and then we will bind this collection to drop down control.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
namespace EntiryFramework
{
    public partial class Main3 : Form
    {
        private OrdersEntities orders;
        public Main3()
        {
            InitializeComponent();
        }

        private void Main3_Load(object sender, EventArgs e)
        {
            orders = new OrdersEntities();
            List<SelectCustomers_Result> selectCustomers;
            selectCustomers = orders.SelectCustomers().ToList();
            
            try
            {
                // Bind the ComboBox control to the query, 
                // which is executed during data binding.
                // To prevent the query from being executed multiple times during binding, 
                // it is recommended to bind controls to the result of the Execute method. 
                this.customerList.DisplayMember = "LastName";
                this.customerList.ValueMember = "CustomerID";
                this.customerList.DataSource = selectCustomers;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        
    }
}

When you run the project, you will see customers loaded in the drop down list


Don't worry about the grid view below. In next post we will use stored procedure to insert a new address and update an existing address.

Thank you.