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.