LINQ Equivalent to SQL “IN” Operator

This is an example of how you can use the LINQ “Contains” in a similar way to how you use the SQL “IN” operator.

The code example below will use an XDocument object as our data that we would like to query. The XDocument contains a set of books where each book as a unique ID. 

We are going to use the .Contains extension to filter out the books that have an ID of 1, 3, and 5.


void Main()
{
	XDocument doc = GetBooks();
	
	Console.WriteLine(string.Format("Show all books\r\n{0}", doc));
	
	// A string array that will be used to as our Book ID filter. 
	// You can think of this array as the arguments that are used in the SQL "IN" operator
	string[] bookIds = new string[] {"1","3","5"};
	
	// Get books out of the xml object that have an ID of 1, 3, or 5
	var books = from b in doc.Descendants("Book")
				where bookIds.Contains(b.Element("ID").Value)
				select b;
			
	Console.WriteLine("\r\nShow the filtered books");
	foreach(var b in books)
		Console.WriteLine(b);
}

XDocument GetBooks()
{ 
  // Manually create an XML document that contain books
	XDocument doc = new XDocument(
		new XElement("Books",
			new XElement("Book",
				new XElement("Title", "Don Quixote"),
				new XElement("ID", 1),
				new XElement("Author", "Miguel de Cervantes")
				),
			new XElement("Book",
				new XElement("Title", "A Tale of Two Cities"),
				new XElement("ID", 2),
				new XElement("Author", "Charles Dickens")
				),
			new XElement("Book",
				new XElement("Title", "The Little Prince"),
				new XElement("ID", 3),
				new XElement("Author", "Antoine de Saint-Exupéry")
				),
			new XElement("Book",
				new XElement("Title", "The Da Vinci Code"),
				new XElement("ID", 4),
				new XElement("Author", "Dan Brown")
				),
			new XElement("Book",
				new XElement("Title", "The Catcher in the Rye"),
				new XElement("ID", 5),
				new XElement("Author", "J.D. Salinger")
				)));
				
		return doc;
}

This is the output of the code above…

Show all books
<Books>
  <Book>
    <Title>Don Quixote</Title>
    <ID>1</ID>
    <Author>Miguel de Cervantes</Author>
  </Book>
  <Book>
    <Title>A Tale of Two Cities</Title>
    <ID>2</ID>
    <Author>Charles Dickens</Author>
  </Book>
  <Book>
    <Title>The Little Prince</Title>
    <ID>3</ID>
    <Author>Antoine de Saint-Exupéry</Author>
  </Book>
  <Book>
    <Title>The Da Vinci Code</Title>
    <ID>4</ID>
    <Author>Dan Brown</Author>
  </Book>
  <Book>
    <Title>The Catcher in the Rye</Title>
    <ID>5</ID>
    <Author>J.D. Salinger</Author>
  </Book>
</Books>

Show the filtered books

<Book>
  <Title>Don Quixote</Title>
  <ID>1</ID>
  <Author>Miguel de Cervantes</Author>
</Book>
<Book>
  <Title>The Little Prince</Title>
  <ID>3</ID>
  <Author>Antoine de Saint-Exupéry</Author>
</Book>
<Book>
  <Title>The Catcher in the Rye</Title>
  <ID>5</ID>
  <Author>J.D. Salinger</Author>
</Book>

Advertisements

How to check if string exists in a List<string>

If you need to determine whether or not a string exists within a List<string>, you may want to ignore the case of the strings while doing the compare.

Thanks to an extension method that hangs off of the List<T>.Contains() method, this is very easy to do.

Say you have a List<string> which contains email addresses and you want to check to see if a specific email address exists within the List<string>, your code may look like this:

List<string> emails = new List<string>() {“keean@domain.com”, “ty@domain.com”, “milo@domain.com” };

string target = “KEEAN@domain.com”;

if (emails.Contains(target, StringComparer.OrdinalIgnoreCase))

    Console.WriteLine(“{0} exists in the list.”, target);

else

    Console.WriteLine(“{0} does not exist in the list.”, target);

For more information on the StringComparer class, read this MS article.

If you use the StringComparer class, you will notice that there are three “IgnoreCase” properties:

  1. StringComparer.CurrentCultureIgnoreCase
  2. StringComparer.InvariantCultureIgnoreCase
  3. StringComparer.OrdinalIgnoreCase

These are enumerations that specifies the culture, case, and sort rules to be used by certain overloads of the String.Compare and String.Equals methods. For more information, check out this article.

Simple Example of Extension Methods in C#

Let’s say you have a C# class named Person that has a property and a method.

Here’s the Person class:

    1 public class Person

    2 {

    3     public string Name { get; set; }

    4     public string Speak()

    5     {

    6         return (string.Format(“The time is {0}.”, DateTime.Now.TimeOfDay.ToString());

    7     }

    8 }

Now let’s say that, for whatever the reason, you are not allowed to make any changes to the Person class (For example, you have been given the class in the form of a .dll assembly). As you are writing your code and consuming the Person class, you run into an issue such that you need for the Person class to return the favorite number of the Person instance. In other words, as the consumer of  the Person class, you wish the class was designed like this:

    1 public class Person

    2 {

    3     public string Name { get; set; }

    4

    5     public string Speak()

    6     {

    7         return (string.Format(“The time is {0}.”, DateTime.Now.TimeOfDay.ToString());

    8     }

    9

   10     public int FavoriteNumber()

   11     {

   12         return (new Random().Next());

   13     }

   14 }

Notice the added method named FavoriteNumber().

Well, since you are not allowed to modify the Person class, what do you do?

This is where Extension Methods can be a great help.
MSDN defines Extension Methods as:

Extension methods enable you to “add” methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.

Using the Extension Methods model, we can implement a method that “feels” like it is a member of the Person class without making any change to the Person class. Here’s how we can do that…

  1. We are not allowed to make any changes to the Person class, so we’ll leave that alone
  2. We’ll create a new class and name it ExtensionsLibrary

        1 public static class ExtensionsLibrary

        2 {

        3     public static int FavoriteNumber(this Person person)

        4     {

        5         // Return a random number for our example

        6         return (new Random().Next());

        7     }

        8 }

    The ExtensionsLibrary is a class that we can add extension methods to. The class must be a static class. If we don’t specify it as a static class we will get the exception:
    Extension method must be defined in a non-generic static class.
    In this example we have only one extension method that we named “FavoriteNumber”. The extension method must also be static. The first parameter (Person person) which type the method operates on – this is where the magic occurs. The first parameter is how we tell the compiler that the FavoriteNumber is extending the Person class. Lastly, we must precede the first parameter with the “this” modifier.

  3. Now this is how you can use the Person class and call the extension method

        1 class Program

        2 {

        3     static void Main(string[] args)

        4     {

        5         // Create a Person instance

        6         Person p = new Person { Name = “Frank” };

        7

        8         // Call the Extension Method to get the Person’s favorite number

        9         int favNumber = p.FavoriteNumber();

       10

       11         Console.WriteLine(“{0} says {1}\r\n{0}’s favorite number is {2}.”, p.Name, p.Speak(), favNumber);

       12         Console.ReadLine();

       13     }

       14 }

Here’s a video that demonstrates how to create extension methods for strong types and generic types.