Biography:

Location: Dayton, OH
College: Cedarville University, Cedarville, OH
Degree: B.A. Management Information Systems (2002)
Certifications: Microsoft Certified Professional (MCP) 2002

Interests:

Music, Playing Guitar, Working on Cars, Home Improvement, Photography, Computers, Website Programming, Driving in the snow, NHL Hockey, Sand Volleyball, Settlers of Catan board game

Favorites:

Foods: Lasagna, Carrot Casserole, Chicken Parmesan
Sports: Hockey, Football, Volleyball, Soccer
Desserts: Peanut Butter Pie, Peanut Butter Passion ice cream
TV Shows: 24, The Office, The IT Crowd, Heroes, Mythbusters, Top Gear, Fifth Gear, Modern Marvels, Seinfeld, Simpsons

Employment Information:

Current Resume: Download .doc


Contact Me:
Use this area to send me a note or message:
Name:
Email:
Comments:
Security Code:

Fun links you should probably check out:


Fun games you might want to play:


Current Code Samples:


Future Code Samples:

  • CAPTCHA form-protection of images using PHP and GD 2.0 library
  • Resizing images using PHP and the GD 2.0 library
  • Rotating images using PHP and the GD 2.0 library
CODE TUTORIAL: Using ternary operators with LINQ-to-XML for multiple WHERE clauses
I've done some searching around for Dynamic Where Clauses for LINQ-to-XML, and found the DynamicLinq library from Microsoft, but it appears it only supports LINQ-to-SQL which is a bit depressing.

Business Problem

I have a search form in my WPF Application that needs to have 8 input boxes/criteria for searches. Some are dropdowns, others are textboxes, and I am assured that each input can only have one value. (This example breaks if you want multiple inputs I think). Since I can be assured that each input can only have one value, I can use some boolean/ternary operators to selectively filter what belongs in the WHERE clause of my LINQ statement.


Screenshot of WPF Form:



C# Code Setup/Preparation:

First, I made a simple public ENUM in my application's namespace to store the values I wanted to use for MatchType:



Then, I wrote some simple code to retrieve the values from my input form and save them to local variables:



Finally, I wrote a pretty massive LINQ query using the ternary operator syntax: (I'll explain the logic below)



Ok, so the where clause of this LINQ statement is pretty complex, but I hope to explain this clearly enough to make it understandable for everyone.

C#.NET CODE: "LINQ-to-XML Multiple Conditional Where Using Ternary Operators"
(PartsBookTitle.Length == 0 ? true :

This line uses basic ternary operator syntax to state that if the PartsBookTitle variable has a length of 0 characters that we return boolean TRUE, otherwise we continue to the next condition (which is wrapped onto the next line)

C#.NET CODE: "LINQ-to-XML Multiple Conditional Where Using Ternary Operators"
(mtPartsBookTitle == (MatchType)1 ? (result.Element("titles").Element("title").Value.ToString().Equals(PartsBookTitle)) :

This 2nd line of the where clause is only fired when the first line of the where clause returns boolean FALSE. This line will use another ternary operator to evaluate the mtPartsBookTitle variable to see if it matches our MatchType ENUM of 1. If so, then the first part of the ternary operation will fire, checking the <titles> element's child element <title> where it's Value is equal to the PartsBookTitle string variable. However, if mtPartsBookTitle is not MatchType of 1, then we continue down to the 3rd line of the where clause.


Hopefully you can see how I'm simply repeating this logic flow for MatchTypes of 2, 3, and 4. I'm also reproducing this logic for other input form variables such as ModelNumber and MediaNumber. Other input fields (that do not have multiples in my XML document) are handled slightly differently. Notice how Region and Brand variables are checked with a more simple variant of this ternary operation.


The Entire LINQ-to-XML Code Snippet:

C#.NET CODE: "LINQ-to-XML Multiple Conditional Where Using Ternary Operators"
//  Select all <mediaNumber> elements matching this MediaNumber value
var searchResults = from result in _xDoc.Element("root").Element("mediaNumberIndex").Elements("mediaNumber")
           where
            (PartsBookTitle.Length == 0 ? true :
                (mtPartsBookTitle == (MatchType)1 ? (result.Element("titles").Element("title").Value.ToString().Equals(PartsBookTitle)) :
                    (mtPartsBookTitle == (MatchType)2 ? (result.Element("titles").Element("title").Value.ToString().StartsWith(PartsBookTitle)) :
                        (mtPartsBookTitle == (MatchType)3 ? (result.Element("titles").Element("title").Value.ToString().EndsWith(PartsBookTitle)) :
                            (mtPartsBookTitle == (MatchType)4 ? (result.Element("titles").Element("title").Value.ToString().Contains(PartsBookTitle)) : true)
                        )
                    )
                )
            )
            &&
            (ModelNumber.Length == 0 ? true :
                (mtPartsBookTitle == (MatchType)1 ? (result.Element("models").Element("model").Value.ToString().Equals(ModelNumber)) :
                    (mtPartsBookTitle == (MatchType)2 ? (result.Element("models").Element("model").Value.ToString().StartsWith(ModelNumber)) :
                        (mtPartsBookTitle == (MatchType)3 ? (result.Element("models").Element("model").Value.ToString().EndsWith(ModelNumber)) :
                            (mtPartsBookTitle == (MatchType)4 ? (result.Element("models").Element("model").Value.ToString().Contains(ModelNumber)) : true)
                        )
                    )
                )
            )
            &&
            (Region.Length == 0 ? true : (result.Element("regions").Element("region").Value.ToString().Equals(Region)))
            &&
            (Brand.Length == 0 ? true : (result.Attribute("brand").Value.ToString().Equals(Brand)))
            &&
            (MediaNumber.Length == 0 ? true :
                (mtMediaNumber == (MatchType)1 ? (result.Attribute("number").Value.ToString().Equals(MediaNumber)) :
                    (mtMediaNumber == (MatchType)2 ? (result.Attribute("number").Value.ToString().StartsWith(MediaNumber)) :
                        (mtMediaNumber == (MatchType)3 ? (result.Attribute("number").Value.ToString().EndsWith(MediaNumber)) :
                            (mtMediaNumber == (MatchType)4 ? (result.Attribute("number").Value.ToString().Contains(MediaNumber)) : true)
                        )
                    )
                )
            )
           select result;

Hope this helps someone else out!


- Justin Tubbs