How to Use “Is Null” With LINQ to SQL

In SQL Server, a SQL statement like 'NULL=NULL' evaluates to false. however 'NULL IS NULL' evaluates to true. So, for NULL values in your database columns, you need to use the 'IS' operator instead of the regular '=' operator.

The problem is, in Linq to SQL, there is no such 'IS' operator since 'IS' is already used as a C# language keyword. So, when you are invoking an equality check in your Linq to SQL where clause to a nullable column you need to be alert on this behavior.

For example, take the following sample code that I wrote to demonstrate this topic.

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

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyDataContext context = new MyDataContext();
            context.Log = new ConsoleWriter();
            string name = null;

            var aff = from a in context.Affiliates
                      where a.CompanyName == name
                      select a.ID;

            var aff2 = from a in context.Affiliates where a.CompanyName == null select a.ID;

            aff.ToList();
            aff2.ToList();
        }
    }
}

In this code, I have attached a sample logger to my DataContext so that all my queries are logged. Now I ran two queries. Lets take a look at the first query and its logger output,

string name = null;

var aff = from a in context.Affiliates
             where a.CompanyName == name
             select a.ID;

The logger output after executing this query is, as follows -

SELECT [t0].[ID]
FROM [dbo].[Affiliates] AS [t0]
WHERE [t0].[CompanyName] = @p0

– @p0: Input VarChar (Size = 0; Prec = 0; Scale = 0) [Null]

 

So, you see that although a null is assigned in the variable 'name', the Linq to SQL generated query uses the '=' operator which may lead to undesired results.

However, the second query and its logger output looks like the following -

var aff2 = from a in context.Affiliates where a.CompanyName == null select a.ID;

SELECT [t0].[ID]
FROM [dbo].[Affiliates] AS [t0]
WHERE [t0].[CompanyName] IS NULL

Here, the generated query uses the 'IS' operator which is desirable.

In case, you want Linq to SQL to generate the first code using 'IS' operator, you may use something like the following one -

var aff3 = from a in context.Affiliates
             where ((name == null && a.CompanyName == null)  || (a.CompanyName == name))
             select a.ID;

This query produces the following SQL code -

SELECT [t0].[ID]
FROM [dbo].[Affiliates] AS [t0]
WHERE ([t0].[CompanyName] IS NULL) OR ([t0].[CompanyName] = @p0)

So, to end, whenever you are writing a where clause on a nullable column using Linq to SQL, make sure you know the consequences and take measures accordingly.

share save 171 16 How to Use Is Null With LINQ to SQL

How to Use LINQ OfType

The LINQ OfType operator can be used to return objects of a certain type from an array. For example, if we have an array of objects which contains both strings and numbers, we can use the LINQ OfType operator to return only strings or only numbers

LINQ OfType Example – Return Only Strings

object[] goop = { "string1", 2, 5, "string2", "string3" };

var onlyStrings =
  from g in goop.OfType<string>()
  select g;
foreach (var item in onlyStrings)
  Console.WriteLine(item);

The result will be

string1
string2
string3

 
I can modify the query to extract only integers which will look like this:

LINQ OfType Example – Return Only Integers

var onlyStrings =
  from g in goop.OfType<int>()
  select g;

With a result of:

2
5


While it is not good practice to have an array which contains strings and integers, we could be working with some legacy code. The LINQ OfType operator will come in handy in such situations.

share save 171 16 How to Use LINQ OfType

How to Create a Tag Parser

Today's post is non-LINQ related…

Download the Tag Parsing Source Code:Tag Parser Engine.zip (6.93 kb)

Recently, I had the need to create a document with markup tags (similar to how HTML uses <b></b>, for example). I wanted a simple, easy solution for parsing out the tags in the document, something that could be easily reused.

I found one solution on CodeProject (Tag Parser). While the author's idea was very good, I found his implementation to have some problems – most notably with returning each tag found via an event, instead of returning a list of the tags from the function call. So, I heavily modified the original idea (adding comments, reorganizing functions, improving efficiency in functions, returning results from the function call instead of through an event). 

This code will allow you take a string of text and parse out the tags. A tag starts with "<" and ends with "/>" (just like XHTML). Tags have a name, such as "link", and have attributes which hold additional information about the tag (such as "href" or "text"). An example tag would be:

<link href="http://www.google.com" text="Google" />

The tag is "link", and has attributes "href" and "text".

Note: As of this writing, there is one caveat to using this code – the tag attributes must be in the same order as created in the AttributesCollection. In the example below, "href" must always come before "text".

The example below will parse the following string:

const string myContent = @"Sample Content <link href=""http://google.com"" text=""Click to Google""/> Some blah text <link href=""http://blog.linqexchange.com"" text=""LINQ Exchange"" />";

And return the following results: 

tag blog How to Create a Tag Parser

We first need to define our Attributes class. We also define an AttributesCollection which will allow our tag class to handle multiple attributes on a tag.

Tag Attribute Class

using System;

namespace TagParser
{
    /// <summary />
    /// Class to define attribute of a tag
    /// </summary />
    public class TagAttribute
    {
        public string Name { get; set; }
        public string Value { get; set; }

        private UInt16 _ordinal = 1;
        public UInt16 Ordinal
        {
            get { return _ordinal; }
            set { _ordinal = value; }
        }
    }

    /// <summary />
    /// Collection of attributes
    /// </summary />
    public class TagAttributeCollection : System.Collections.Generic.List<TagAttribute>
    {
        private UInt16 ordinal = 1;
        public new void Add(TagAttribute attr)
        {
            attr.Ordinal = ordinal;
            ordinal++;
            base.Add(attr);
        }
    }
}

Next, we need to define an Interface to hold the tag information. When we run the tag parser, we will create a custom class using this Interface as the template for storing the tag information.

Tag Parser Interface

using System;

namespace TagParser
{
    /// <summary />
    /// Interface to define your own tag
    /// </summary />
    public interface ITag
    {
        /// <summary />
        /// Property to get the Prefix for your tag.
        /// e.g. <link href="http://google.com"
        ///             text="Click to Google"/>
        /// Over here link is your Prefix.
        /// </summary />
        string Prefix
        {
            get;
        }

        /// <summary />
        /// Property to get an indication whether the parsing
        /// should be case sensitive or not.
        /// Return true if you want case sensitive matching
        /// </summary />
        bool IsCaseSensitive
        {
            get;
        }

        /// <summary />
        /// Property to get the Type of tag. Return a small description.
        /// e.g. anchor
        /// </summary />
        string Type
        {
            get;
        }

        /// <summary />
        /// Property to get the Attributes of tag.
        /// In case of <link href="http://google.com"
        ///         text="Click to Google"/> href and
        /// text are two attributes.
        /// </summary />
        TagAttributeCollection TagAttributes
        {
            get;
        }

        /// <summary>
        /// Clone this object to another object
        /// </summary>
        ITag Clone();
    }
}

Now that we have the Interface defined, let's see how you would create the class which holds tag parsing information.You can create multiple tag parsing classes using this technique, which allows you to only need to have one instance of the parsing engine object.

Notice the Clone() function. This is used by the tag parsing engine to get a new instance of the tag info, but retain the name/type/attributes data. Since we haven't done any work with the data in this class, we can just return a new instance of the class (which will populate the properties for us).

Example Tag Parsing Info Class

    /// <summary>
    /// A sample class showing how you can define your own tag to be parsed.
    /// </summary>
    public class MyExampleTag : ITag
    {
        private static TagAttributeCollection attrCollection;

        #region ITag Members

        public ITag Clone()
        {
            return new MyExampleTag();
        }

        public string Prefix
        {
            get { return "link"; }
        }

        public bool IsCaseSensitive
        {
            get { return false; }
        }

        public string Type
        {
            get { return "anchor"; }
        }

        public TagAttributeCollection TagAttributes
        {
            get
            {
                if (attrCollection == null)
                {
                    attrCollection = new TagAttributeCollection();

                    TagAttribute attrHref = new TagAttribute();
                    attrHref.Name = "href";
                    attrCollection.Add(attrHref);

                    TagAttribute attrText = new TagAttribute();
                    attrText.Name = "text";
                    attrCollection.Add(attrText);

                    TagAttribute attrTarget = new TagAttribute();
                    attrTarget.Name = "target";
                    attrCollection.Add(attrTarget);
                }
                return attrCollection;
            }
        }
        #endregion
    }

Finally, the tag parsing engine. This is where the actual tag parsing is done. Regular Expressions are used heavily in this class. 

Tag Parsing Engine

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Text;

namespace MerlinWebsiteHelperEx.TagParser
{
    public class clsTagParser
    {
        #region Variables

        private const string HTML_TAG_REGEX_PATTERN =
         @"<([A-Za-z_:]|[^\x00-\x7F])([A-Za-z0-9_:.-]|" +
         @"[^\x00-\x7F])*([ \n\t\r]+([A-Za-z_:]|[^\x00-\x7F])" +
         @"([A-Za-z0-9_:.-]|[^\x00-\x7F])*([ \n\t\r]+)?=([ \n\t\r]+)" +
         @"?(""[^<""]*""|'[^<']*'))*([ \n\t\r]+)?/?>";

        private const string CONTENT_TAG_REGEX_PATTERN = @"<{0}\b(?>\s+(?:{1})|[^\s>]+|\s+)*>";
        private const string CONTENT_TAG_ATTRIBUTE_REGEX_PATTERN = @"{0}=""([^""]*)""";

        private Regex contentTagRegex;
        private ITag contentTag;

        // Variables
        #endregion

        #region Properties

        private static Regex tagRegEx;
        private static Regex TagRegEx
        {
            get
            {
                if (tagRegEx == null)
                {
                    tagRegEx =
                      new Regex(HTML_TAG_REGEX_PATTERN
                          , RegexOptions.Singleline
                          | RegexOptions.IgnoreCase
                          | RegexOptions.CultureInvariant
                          |
                            RegexOptions.IgnorePatternWhitespace);
                }
                return tagRegEx;
            }
        }

        // Properties
        #endregion

        #region Public Functions

        /// <summary>
        /// Parses a string to find matching tags
        /// </summary>
        /// <param name="content">the string to parse</param>
        /// <param name="tag">the tag information to find</param>
        public List<ITag> Parse(string content, ITag tag)
        {
            List<ITag> retList = new List<ITag>();

            // set the tag information, used by other functions
            contentTag = tag;

            // build our regex string
            ConstructHTMLTagRegex();
            foreach (Match m in TagRegEx.Matches(content))
            {
                // read the tag and convert to itag
                ITag matchedTag = ReadTag(m);

                // if we found something, add to the list
                if (matchedTag != null)
                    retList.Add(matchedTag);
            }

            // return the list
            return retList;
        }

        // Public Functions
        #endregion

        #region Private Functions

        /// <summary>
        /// Build the regex used to find our tags in the content string
        /// </summary>
        private void ConstructHTMLTagRegex()
        {
            // build the attrible regex string
            StringBuilder sbAttributeRegex = new StringBuilder();
            foreach (TagAttribute attribute in contentTag.TagAttributes)
            {
                sbAttributeRegex.AppendFormat("{0}|", string.Format(
                    CONTENT_TAG_ATTRIBUTE_REGEX_PATTERN, attribute.Name));
            }

            // build the pattern string
            string tagRegexPattern = string.Format(CONTENT_TAG_REGEX_PATTERN,
               contentTag.Prefix, sbAttributeRegex);

            // build the content regex, which is used for finding our tags
            contentTagRegex = new Regex(tagRegexPattern,
                              RegexOptions.Singleline |
                              (contentTag.IsCaseSensitive ?
                               RegexOptions.Singleline :
                               RegexOptions.IgnoreCase)
                              | RegexOptions.CultureInvariant
                              |
                                RegexOptions.IgnorePatternWhitespace);
        }

        /// <summary>
        /// Find tags in the regex match
        /// </summary>
        /// <param name="match">the matched tag</param>
        private ITag ReadTag(Match match)
        {
            // exit if nothing passed in
            if (match == null)
                return null;

            // find the tag itself
            Match matchTag = contentTagRegex.Match(match.Value);

            //Match successful
            return (matchTag.Success) ? ReadAttributes(matchTag) : null;
        }

        /// <summary>
        /// Get the attributes of the tag
        /// </summary>
        /// <param name="match">the tag to be read</param>
        private ITag ReadAttributes(Match match)
        {
            // set the return tag information
            ITag rTag = contentTag.Clone();

            int attribCount = contentTag.TagAttributes.Count;

            // loop through the attributes in the original
            // tag's attribute collection. Find any matches in the
            // content string
            for (int i = 0; i < attribCount; i++)
            {
                // get the attribute to test
                TagAttribute attr = contentTag.TagAttributes[i];

                // get the attribute value
                string attrValue = GetGroupCollectionValue(match.Groups, attr.Ordinal);
               
                // if we have a value, add to the collection
                if (!string.IsNullOrEmpty(attrValue))
                    rTag.TagAttributes[i].Value = attrValue;
            }

            // return the tag
            return rTag;
        }

        /// <summary>
        /// Returns the value for this attribute
        /// </summary>
        /// <param name="gc">the group to search</param>
        /// <param name="gcIndex">the index this attribute can be found</param>
        /// <returns></returns>
        private string GetGroupCollectionValue(GroupCollection gc, int gcIndex)
        {
            string namedItemValue = string.Empty;
            try
            {
                namedItemValue = gc[gcIndex].Captures[0].ToString();
            }
            //explicitly eating up the exception to make this method generic
            //for all replacements.
            catch { }
            return namedItemValue;
        }
               
        // Private Functions
        #endregion
    }
}

 

Now that we have all the code done, here is an example console app which demonstrates how to parse out the tags.

Tag Parsing Example Console Application

    class Program
    {
        static void Main(string[] args)
        {
            const string myContent = @"Sample Content <link href=""http://google.com"" text=""Click to Google""/> Some blah text <link href=""http://blog.linqexchange.com"" text=""LINQ Exchange"" />";

            //There can be multiple tags of different kinds in your application.
            //Repeat the call to tp.Parse
            //with your respective ITag type
            clsTagParser tp = new clsTagParser();
            List<ITag> tagList = tp.Parse(myContent, new MyExampleTag());

            // output results
            foreach (ITag itag in tagList)
            {
                Console.WriteLine(string.Format("Tag Type is: {0}", itag.Type));
                Console.WriteLine("Attributes for the tag are:");

                // output this tag's attributes
                foreach (TagAttribute attr in itag.TagAttributes)
                {
                    Console.WriteLine(
                        string.Format(
                            "\tAttribute Name: {0}\tAttribute Value: {1}",
                            attr.Name, attr.Value));
                }
            }

            Console.ReadLine();
        }
    }

Download the Tag Parsing Source Code:Tag Parser Engine.zip (6.93 kb)

share save 171 16 How to Create a Tag Parser

How to Use LINQ.GroupBy

LINQ query expressions intentionally look like SQL, because SQL is a non-procedural query language that many developers are already familiar with, so it gives developers a familiar frame of reference.

One of the fundamental differences between LINQ and SQL is that where SQL always projects rectangular result sets, LINQ has the capability of projecting hierarchical result sets. This hierarchical result set can be demonstrated in the code below, which creates an array of an anonymous type containing two properties each.  It then groups them by age.  We can then iterate through the results using nested for loops.

LINQ.GroupBy Example

// anon typed array
var people = new[] {
    new { Name = "Bob", Age = 3 },
    new { Name = "Bill", Age = 3 },
    new { Name = "Mary", Age = 4 },
    new { Name = "June", Age = 3 },
    new { Name = "Nancy", Age = 4 },
    new { Name = "Shelly", Age = 4 },
    new { Name = "Cheryl", Age = 3 },
    new { Name = "Joe", Age = 3 }
};

// group by the age
var groupedByAge =
    people.GroupBy(s => s.Age);

 
// loop through and print results
foreach (var group in groupedByAge)
{
    // group implements IGrouping
    Console.WriteLine("Group of people aged {0}", group.Key);
    foreach (var person in group)
    {
        // person is an instance of the above anonymous type
        Console.WriteLine(person);
    }
    Console.WriteLine();
}

 
Output:
Group of people aged 3
{ Name = Bob, Age = 3 }
{ Name = Bill, Age = 3 }
{ Name = June, Age = 3 }
{ Name = Cheryl, Age = 3 }
{ Name = Joe, Age = 3 }
 

Group of people aged 4
{ Name = Mary, Age = 4 }
{ Name = Nancy, Age = 4 }
{ Name = Shelly, Age = 4 }

share save 171 16 How to Use LINQ.GroupBy

How to Speed Up LINQ to Sql With Compiled Queries

One of the drawbacks of LINQ to SQL is that the SQL statement is built dynamically so it needs to be parsed and compiled each time you run it. The System.Data.LINQ namespace provides a solution in a class named CompiledQuery. This class is responsible for caching the compiled version of a LINQ to SQL query. CompiledQuery has a static method called Compile, which takes a Func<T,S,R> delegate. In this signature, T is the type of a DataContext (i.e. HRMDataContext) , S is the type of a predicate to filter the query and R is the type of returned result, which must be IQueryable<T>.

The CompiledQuery class allows us to pre-compile a query. This pre-compilation provides a marked increase in execution speed.To pre-compile a query we must define a public static field of type Func<T,S,R>

public static Func<testDataContext , SearchCriteria, IQueryable<Person>> FilteredResult

In the above line, testDataContex is the type of a DataContext inside the project, SearchCriteria is type of a class or struct that is designed for passing search criteria to .Compile method. For example, suppose that in testDataContext, we have a Table named Person. We have also defined a class (or struct) named SearchCriteria as bellow:

public class SearchCriteria
{
    public int id { set; get; }
    public string FirstName { set; get; }
    public string LastName { set; get; }
}

 

Example Using a LINQ to SQL Compiled Query

public static Func<testDataContext , SearchCriteria, IQueryable<Person>> FilteredResult =
    System.Data.LINQ.CompiledQuery.Compile(
        (testDataContext dc , SearchCriteria criteria ) =>
            from p in dc.Persons
            where (p.id == criteria.id || criteria.id == -1)
            && (p.FirstName == criteria.FirstName || criteria.FirstName == string.Empty)
            && (p.LastName == criteria.LastName || criteria.LastName == string.Empty)
            select p
        );


That’s it. At this point, FilteredResult contains a pre-compiled query and can be used this way:

testDataContext dc = new testDataContext();
SearchCriteria criteria = new SearchCriteria();
criteria.id = -1;
criteria.FirstName = "Bill";
criteria.LastName = "Gates";
List<Person> p = FilteredResult(dc, criteria).ToList();


The above code creates instances of testDataContext (dc) and SearchCriteria (criteria) and passes them to FilteredResult as arguments. The result of FilteredResult is IQueryable<Person> we have called .ToList() extension method to get a List<Person> series.

One catch to using pre-compiled queries is that you cannot use a stored-procedure to make a compiled query. In the above LINQ to SQL code, if you write "from C in usp_GetPerson()" you will get an error indicating that stored procedures are not allowed.

Below is a small Console application that runs two version (one is compiled and one is not) of a query over a database for 1000 times. The time needed to run each query is as follows:

Compiled Query takes 0 minutes, 1 seconds and 62 milliseconds.

Regular Query takes 0 minutes, 13 seconds and 328 milliseconds.


The compiled query is greatly faster than a regular query. Notice that in a LINQ model, nothing will really happen unless we iterate over the result of the query. Therefore, I have forced the queries to execute by calling ToList() on each query. I also have written a small query at the beginning of the program to make LINQ manager open a connection to SQL Server. A connection must be open before the CompiledQuery executes, or an error is raised.

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

namespace CompiledQuery
{
    class Program
    {
        public static Func<testDataContext, SearchCriteria, IQueryable<Person>> FilteredResult =
            System.Data.Linq.CompiledQuery.Compile(
                (testDataContext dc, SearchCriteria criteria) =>
                from p in dc.Persons
                where (p.id == criteria.id || criteria.id == -1)
                && (p.FirstName == criteria.FirstName || criteria.FirstName == string.Empty)
                && (p.LastName == criteria.LastName || criteria.LastName == string.Empty)
                select p
            );

        static void Main(string[] args)
        {
            testDataContext dc = new testDataContext();
            SearchCriteria criteria = new SearchCriteria();
            IQueryable<Person> Q = null;

            // The following code makes Linq manager to open a connection to SQL Server
            // by calling a stored procedure
            dc.sproc_DoNothing_Procedure().ToList();

            criteria.id = -1;
            criteria.FirstName = "Bill";
            criteria.LastName = "Gates";
            DateTime BeginTime = DateTime.Now;

            // test Compiled Query
            for (int i = 0; i < 1000; i++)
                FilteredResult(dc, criteria).ToList();

            DateTime EndTime = DateTime.Now;
            TimeSpan Diff1 = EndTime – BeginTime;

            BeginTime = DateTime.Now;

            // Test non-compiled querey
            for (int i = 0; i < 1000; i++)
            {
                (from p in dc.Persons
                 where (p.id == criteria.id || criteria.id == -1)
                 && (p.FirstName == criteria.FirstName || criteria.FirstName == string.Empty)
                 && (p.LastName == criteria.LastName || criteria.LastName == string.Empty)
                 select p).ToList();
            }

            EndTime = DateTime.Now;
            TimeSpan Diff2 = EndTime – BeginTime;

            Console.WriteLine("Compiled query takes : {0}:{1}:{2}", Diff1.Minutes, Diff1.Seconds, Diff1.Milliseconds);
            Console.WriteLine("Regular query takes {0}:{1}:{2}", Diff2.Minutes, Diff2.Seconds, Diff2.Milliseconds);

            Console.ReadKey();
        }
    }

    public class SearchCriteria
    {
        public int id { set; get; }
        public string FirstName { set; get; }
        public string LastName { set; get; }
    }
}

 

share save 171 16 How to Speed Up LINQ to Sql With Compiled Queries

Using Parallel LINQ

The LINQ Team at Microsoft is working on extensions to Language Integrated Query (LINQ) referred
to as Parallel LINQ (PLINQ). PLINQ makes it easy to use multiple
threads and all that processing power. This article shows you how and
provides some parameters and guidelines for when you can get some extra
horsepower out of multithreading your LINQ queries.

To Multithread or Not to Multithread?

Some things, like file I/O, are inherently sequential. Other kinds
of things can benefit from multithreading. Candidates for
multithreading and parallel LINQ are algorithms that are
computationally complex; for example, collections with very large data
sets. Parallel LINQ (available by searching online for "parallel LINQ"
or "PLINQ") is a download extension from Microsoft, in beta, that
ultimately will let you write your LINQ queries and use multithreading
too. The beauty, as you will see, is that most of the multithreading
plumbing is handled for you by this extension to LINQ.

When you use PLINQ, keep a few things in mind:

  • Avoid adding ordering clauses.
  • Parallelize outer loops but not inner loops, unless the outer loop's
    range is very small (I equals 0 to 3) and the inner loop is very large
    (j equals 0 to 1000000).

  • Have reasonable expectations. Amdahl's Law suggests that the maximum
    achievable parallel speedup is limited by the amount of sequential code
    remaining. Everyone wants order-of-magnitude performance increases, but
    parallelism alone is unlikely to yield these sorts of returns. (Check
    out Amdahl's Law on Wikipedia.org for details and mathematics.)

Multithreading with PLINQ

It's actually very simple to use multithreading
with LINQ. After you have the Parallel LINQ extensions, call AsParallel on your enumerable collection.

Since the Parallel LINQ extensions are in beta, you need to take a few extra steps to prepare:

  1. You can find the Parallel LINQ extensions on Microsoft
    download pages
    , or use your favorite search engine to find the latest
    release.
  2. Install the Parallel LINQ extensions. By default, the December 2007 Community Tech Preview (CTP) installs here:
    	C:\Program Files\Microsoft Parallel Extensions Dec07 CTP
    	

    This folder contains a version of System.Threading.dll containing the LINQ parallel extensions.

  3. To access the extensions, you'll need to add a reference to the System.Threading.dll
    file contained in the Parallel LINQ folder. Use the Project > Add
    Reference option in Visual Studio and browse to the folder containing
    the downloaded System.Threading.dll in step 2.

Now you're ready.

To use Parallel LINQ, write your LINQ queries as before, include a from clause and select, whatever you need. (Although remember the caveat against ordering.) The from clause contains a range of variables, the keyword in, and the source containing the data to query. For example:

	from num in numbers
	

This statement defines a range num, and the source collection is numbers. Add a call to AsParallel from the source collection numbers:

	numbers.AsParallel()
	

The code below demonstrates the AsParallel method in context.

Using Parallel LINQ to sort a collection of integers.

	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Text;
	using System.Threading;
	using System.Diagnostics;
	namespace PLinqDemo
	{
	class Program
	{
	static void Main(string[] args)
	{
	int[] largeArray = new int[10000];
	Random rnd = new Random(DateTime.Now.Millisecond);
	for(int i=0; i<largeArray.Length; i++)
	{
	largeArray[i] = rnd.Next(10000);
	}
	Stopwatch watch = new Stopwatch();
	watch.Start();
	var results = from num in largeArray.AsParallel()
	where num % 2 == 0
	select new
	{
	Number=num,
	ThreadID=Thread.CurrentThread.ManagedThreadId
	};
	watch.Stop();
	Console.WriteLine(watch.Elapsed.ToString());
	Console.ReadLine();
	}
	}
	}
	

At the time this article was written, PLINQ supported parallel
queries over collections of objects and XML sources. (It is worth
noting that on modern PCs 10,000 integers is not sufficiently complex
to get performance gains; hence, the StopWatch may indicate that the code above actually runs faster without the call to AsParallel.)

AsParallel is overloaded and accepts variations on an integer argument and a ParallelQueryOptions enumeration. The integer argument is the degree of parallelism, or number of threads to use. The ParallelQueryOptions are None and PreserveOrdering. PreserveOrdering preserves the order of elements in the collection.

Handling Concurrent Exceptions

One of the challenges of using threads is concurrent exceptions—that
is, how to handling an exception on one or more additional threads.
Parallel LINQ aggregates all exceptions into an instance of System.Threading.AggregateException, marshaled to the calling thread.

The original exceptions are available through the InnerExceptions property, and an AggregateException is created even if only one background thread throws an exception.

Processing Items with Parallel.ForEach

PLINQ introduces iteration control methods like For and ForEach. ForEach accepts an enumerable collection and a generic Action delegate and performs the action on a background thread. The Action can be satisfied with a Lambda expression:

	Parallel.ForEach(results, r=>Console.WriteLine(r));
	

In the fragment results is the input argument from the LINQ query in Listing 1. The argument r=>Console.WriteLine(r)); writes the anonymous type—the type created in the select clause of Listing 1—to the console.

Lambda expressions are condensed anonymous delegates. The left side of the =>
("goes to" operator) represents the function header and input
arguments, and the right side represents the function body and
statements. The Lambda expression is simply read (or understood) as
"Given a value r, write that value to the console."

Summary

When Parallel LINQ extensions are released, it will be easy to use
multithreading with LINQ. The key is to use parallelism for complex
data sets and for data that can be parallelized. Handle background
exceptions by catching System.Threading.AggregateException, examining the InnerExceptions
property for the actual exceptions. And, finally, Amdahl's Law reminds
us to have reasonable expectations about performance gains achievable
when using multithreading.

For additional reading on LINQ and Lambda expressions, see the book LINQ Unleashed for C# (Sams, August 2008, ISBN 978-0-672-32983-8).

 

Original content for this article came from InformIT.

share save 171 16 Using Parallel LINQ

SQL CE 3.5 with LINQ to SQL

Using LINQ to SQL with SQL CE 3.5 can be
a bit of a challenge.  First off, the LINQ to SQL Visual Studio
designer doesn’t support SQL CE so you need to run sqlmetal
from the command line to create the object model (or write it by
hand).  Once you get past this point then you can use LINQ to SQL the
same way you would for SQL Sever BUT there is a catch.

The way LINQ to SQL is built makes it work well with SQL Server and its connection pooling ability.  If you look at this FAQ under the "Database Connection: Open How Long?" section it says:

A connection typically remains open until you consume the query results.

Therefore given the following code:

   1: using(Northwind db = new Northwind(MyConnectionString))
   2: {
   3:     (from p in db.Products).ToList();
   4:     (from p in db.Customers).ToList();
   5: }

On line 3 and 4 in the above code will open a database connection
(which will be pulled from the open connections in connection pool),
execute the query, and then close the connection after the operation is
completed (which will return the connection to the pool). 

This works great with connection pooling but when you move to SQL CE
you don’t have that luxury.  What happens now is that for each query a
new SQL CE connection will be opened, the query will be executed and
then the connection is closed.  Each query is incurring the cost of
opening a new connection.  To make matters even worse, in SQL CE the
first open connection  brings the database engine into memory, and once
you have no open connections anymore it removes the engine from
memory.  What this means is that each time we close the only open
connection and then re-open we are incurring a HUGE cost.

 

One way to get around this is to pass into the DataContext an open
SQLCeConnection object.  LINQ to SQL will only automatically close a
connection if it opens it.  Therefore, if you pass it an open
connection then you won’t incur this cost over and over again. This
will work fine in a single threaded application but once you move to a
mutlithreaded app where you are performing database operations from
different threads you encounter a problem: The SQLCeConnection object
is not thread safe.  You need to have a different connection object per
thread in order to make this work.  What you want is to be able to
request a connection from any thread and get an already opened one for
that thread.  This sounds a lot like a simple connection pooler, which
could look something like this:

   1: /// <summary>
   2: /// Manages open connections on a per-thread basis
   3: /// </summary>
   4: public class ConnectionPool
   5: {
   6:     private Dictionary<int, IDbConnection> threadConnectionMap;
   7: 
   8:     /// <summary>
   9:     /// Gets the connection string.
  10:     /// </summary>
  11:     /// <value>The connection string.</value>
  12:     public string ConnectionString
  13:     {
  14:         get;
  15:         private set;
  16:     }
  17: 
  18:     /// <summary>
  19:     /// Gets a connection.
  20:     /// </summary>
  21:     /// <returns>An open connection</returns>
  22:     public IDbConnection Connection
  23:     {
  24:         get
  25:         {
  26:             lock (threadConnectionMap)
  27:             {
  28:                 int threadId = Threading.Thread.CurrentThread.ManagedThreadId;
  29: 
  30:                 IDbConnection connection = null;
  31:                 if (threadConnectionMap.ContainsKey(threadId))
  32:                 {
  33:                     connection = threadConnectionMap[threadId];
  34:                 }
  35:                 else
  36:                 {
  37:                     connection = new SqlCeConnection(ConnectionString);
  38:                     connection.Open();
  39:                     threadConnectionMap.Add(threadId, connection);
  40:                 }
  41: 
  42:                 return connection;
  43:             }
  44:         }
  45:     }
  46: 
  47:     /// <summary>
  48:     /// Initializes a new instance of the <see cref="ConnectionPool"/> class.
  49:     /// </summary>
  50:     /// <param name="connectionString">The connection string.</param>
  51:     public ConnectionPool(string connectionString)
  52:     {
  53:         threadConnectionMap = new Dictionary<int, IDbConnection>();
  54:         ConnectionString = connectionString;
  55:     }
  56: }

 

With this you create a DataContext like this:

 
   1: // Defined somewhere
   2: ConnectionPool connectionPool = new ConnectionPool(MyConnectionString);
   3: 
   4: // …
   5: // …
   6: 
   7: using(Northwind db = new Northwind(connectionPool.Connection))
   8: {
   9:     (from p in db.Products).ToList();
  10:     (from p in db.Customers).ToList();
  11: }

Now each thread will have its own open connection which will minimize the cost of opening connections.

 SQL CE 3.5 with LINQ to SQL
This post originated from and is provided by the MSDN Blogs RSS feed. The original post of the article can be found here.

share save 171 16 SQL CE 3.5 with LINQ to SQL

Using LINQ DefaultIfEmpty to Test If an Element Exists

Often you want to run something only if an element exists. There is always the Try/Catch method, but that introduces code overhead and increases resources if the Catch block is called. LINQ provides an extension called DefaultIfEmpty which returns a default value if the item does not exist in the list. The easiest way to do this is to give it something explicitly so you know what it is returning for the default; I just use a dummy instance. For this example, I am using LINQ to XML and XElements.


LINQ DefaultIfEmpty Example:

//make your dummy element
XElement dummy = new XElement("dummy");

//assign it an easy to recognize null value
dummy.Value = "Does Not Exist";

//now run a query with it
foreach (XElement p in xmlFromFile.Elements("anElement").Descendants("someElement").DefaultIfEmpty(dummy))
{
  if(process.Value.Equals(dummy.Value)
    //it does not exist
}

 

Original artcle: http://naspinski.net/post/Using-DefaultIfEmpty-to-check-if-an-element-exists-with-LINQ.aspx 

share save 171 16 Using LINQ DefaultIfEmpty to Test If an Element Exists

Using LINQ ElementAt and LINQ ElementAtOrDefault

LINQ provides two extension methods for retreiving the element at a given index in a List or other IEnumerable object. ElementAt returns the element at a given index, but can throw a System.ArguementOutOfRangeException when the specified index is a
negative value or not less than the size of the sequence. ElementAtOrDefault returns the element at a given index, or the defaultvalue of the list type. For value types (ints and bools for example), the default value is the initial value of the type, which is usually 0. For reference types (objects), the default value is usually null, although this can be overriden.

LINQ ElementAt and LINQ ElementAtOrDefault Example:

// Create a new generic list of ints
List<int> l = new List<int>();

l.Add(1); // Add 1 to the list
l.Add(5); // Add 5 to the list
l.Add(3); // Add 3 to the list

// Returns 1 as 1 exists at index 0
int value = l.ElementAt(0);

// Returns 3 as 3 exists at index 2
value = l.ElementAt(2);

// Returns the default value of int which is 0
// since no element in the list exists at index 3
value = l.ElementAtOrDefault(3);

// Throws System.ArguementOutOfRangeException

// since no element in the list exists at index 3


value = l.ElementAt(3);

 

share save 171 16 Using LINQ ElementAt and LINQ ElementAtOrDefault

Use LINQPad to Help Understand LINQ Queries

I found an interesting program a few days ago called LINQPad. LINQPad lets your write LINQ queries against a SQL database, XML File, or other objects. The developers wrote a book called C# 3.0 in a Nutshell, and they provide over 200 code examples from the book in the LINQPad application.

I tried LINQPad, and found it very easy to use, and kinda fun. I could definitely see using this for prototyping or when you just need some quick results and don't want to have to create a new project.

From the LINQPad Website:

LINQPad supports everything in C# 3.0 and Framework 3.5:

    * LINQ to SQL
    * LINQ to Objects
    * LINQ to XML

LINQPad is also a great way to learn LINQ: it comes preloaded with 200 examples from my book, C# 3.0 in a Nutshell.  There's no better way to experience the coolness of LINQ and functional programming.

And LINQPad is more than just a LINQ query tool: it's a code snippet IDE. Instantly execute any C# 3 or VB 9 expression or statement block!

Best of all, LINQPad is free and needs no installation: just download and run.  The executable is only 2MB and is self-updating. 

 

linqpadscreen Use LINQPad to Help Understand LINQ Queries

 

share save 171 16 Use LINQPad to Help Understand LINQ Queries
 Page 7 of 10  « First  ... « 5  6  7  8  9 » ...  Last »