Sunday, March 14, 2010

LINQ To Entities in WinForm and Better Practice

There is a homework for week 2 UTS Short Course about LINQ To Entities. As a tutor, I find it is interesting and I never use LINQ before, so I spent sometime to do the homework in advance. Here is the homework mock-up and criteria,

















Figure: Mock-Up


Criteria:
On Search Button click, try to use some LINQ  magic to return employees that match that filter
  • Firstname match OR Lastname match
  • Filter on phone number as well
  • Try to filter on birth date if the text in the textbox is a date or the user writes "1979"
  • Try to implement filters like:  “Gfader 1979” returns all people with name Gfader and birthdate year 1979 

I use VS 2010 RC in this solution:














"Form1.cs" is my original version which is messy coding. After I took the advice from Peter about using Regex and reusable Iqueryable object, I create the "BetterPracticeForm.cs". So you can download the solution file if you interested to make a comparison.

In "BetterPracticeForm.cs", when search button fires, It will call the Text Parsing method (using Regex) :

//Format: BirthDate e.g. 22/12/1948
Regex birthDateRegex = new Regex(@"([1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$");

//Format: Phone Number e.g. (206) 555-9857 PS: Space is optional
Regex phoneNumRegex = new Regex(@"\(\d+\)\s?\d+[-]\d+$");

//Format: BirthYear e.g. 1959
Regex birthYearRegex = new Regex(@"(19|20)\d\d$");


Here is the checking if the SearchValue match Regex:

            bool noNameAndBirthYearflag = true;
            bool phoneNumFound = false;
            string phoneNumString = string.Empty;
            if (phoneNumRegex.IsMatch(searchValue))
            {
                phoneNumFound = true;
                phoneNumString = searchValue;
                noNameAndBirthYearflag  = false;
            }

            bool birthDateFound = false;
            string birthDateString = string.Empty;
            if(birthDateRegex.IsMatch(searchValue))
            {
                birthDateFound = true;
                birthDateString = searchValue;
                noNameAndBirthYearflag = false;
            }

            int tmepYear;
            int year = 0;
            bool yearFound = false;
            string[] inputKeywords = searchValue.Split();
            string nameString = string.Empty;

            if(noNameAndBirthYearflag)
            {
                foreach (var inputKeyword in inputKeywords)
                {

                    if (int.TryParse(inputKeyword, out tmepYear))
                    {
                        // number found!
                        if (birthYearRegex.IsMatch(tmepYear.ToString()))
                        {
                            // is a valid year
                            yearFound = true;
                            year = tmepYear;
                        }
                    }
                    else
                    {
                            nameString = inputKeyword;
                    }
                }
            }

 Here is the code of LINQ:

            using (NorthwindEntities data = new NorthwindEntities())
            {
                       var dq = data.Employees.Select(employee => new
                       {
                           employee.FirstName,
                           employee.LastName,
                           employee.Title,
                           employee.BirthDate,
                           employee.HomePhone
                       });

                if(noNameAndBirthYearflag )
                {
                    // Filter on year
                    if (yearFound)
                    {
                        dq = from employee in dq
                             where employee.BirthDate.Value.Year == year
                             select (new
                             {
                                 employee.FirstName,
                                 employee.LastName,
                                 employee.Title,
                                 employee.BirthDate,
                                 employee.HomePhone
                             });
                    }

                    // Filter on firstname lastname
                    if (string.IsNullOrEmpty(nameString) == false)
                    {
                        dq = dq.Where(employee=>(employee.FirstName.Contains(nameString) || employee.LastName.Contains(nameString))).Select(employee => (new
                        {
                            employee.FirstName,
                            employee.LastName,
                            employee.Title,
                            employee.BirthDate,
                            employee.HomePhone
                        }));
                    }
                }
                else
                {
                    // Filter phone number
                    if (phoneNumFound)
                    {
                        dq = from employee in dq
                             where employee.HomePhone == phoneNumString
                             select (new
                             {
                                 employee.FirstName,
                                 employee.LastName,
                                 employee.Title,
                                 employee.BirthDate,
                                 employee.HomePhone
                             });
                    }

                    // Filter birth date
                    if (birthDateFound)
                    {
                        DateTime dt = DateTime.Parse(birthDateString);
                        dq = from employee in dq
                             where
                                 employee.BirthDate.Value.Year == dt.Year && employee.BirthDate.Value.Month == dt.Month &&
                                 employee.BirthDate.Value.Day == dt.Day
                             select (new
                             {
                                 employee.FirstName,
                                 employee.LastName,
                                 employee.Title,
                                 employee.BirthDate,
                                 employee.HomePhone
                             });
                    }
                }
                dataGridViewResult.DataSource = dq;











Figure - Search Phone Number











Figure - Search Birth Date












Figure - Search FirstName Or LastName












Figure - Search Name and Birth Year











Figure - Search Birth Year


Here is the link for code downloading and link for Regex reference.
Also, here is the link from SSW about why we choose LINQ To Entities over LINQ To SQL.

Thanks for Peter giving me advice.

If you think here is any problems in my entry, please leave comments. I really appreciate it.

    1 comment:

    1. Gud work wen. I liked ur post and I dont really know about regex. It would have been gud if you give some comments on regex and its advantages.

      Keep it up.. Will follow up regularly..

      Sunny

      ReplyDelete