How to order DataColumns with LINQ? Is there a very short way to do this same thing in a pure LINQ based way?  It seems like I should not have to do all of this below to get to the OrderBy.

Dictionary&lt;DataColumn, DateTime&gt; columns = new Dictionary&lt;DataColumn, DateTime&gt;();
int startIndex;
int endIndex;
for (int i = 0; i &lt; table.Columns.Count; ++i)
{        
    // these columns need to be sorted
    startIndex = table.Columns[i].Caption.IndexOf('(');
    endIndex = table.Columns[i].Caption.IndexOf(')');
    if (startIndex &gt; 0 &amp;&amp; endIndex &gt; 0)
    {
        // create a standard date
        string monthYear = table.Columns[i].Caption.Substring(
            startIndex + 1, endIndex - startIndex - 1);
        columns.Add(
            table.Columns[i], 
            DateTime.Parse(monthYear.Replace("/", "/01/")).Date);
    }
    else
    {
        // all other columns should be sorted first
        columns.Add(table.Columns[i], DateTime.MinValue);
    }
}

// perform the LINQ order by
columns = columns.OrderBy(o =&gt; o.Value).ToDictionary(o =&gt; o.Key, o =&gt; o.Value);

// order the original table uses the dictionary
for (int i = 0; i &lt; columns.Count; ++i)
{
    table.Columns[columns.Keys.ElementAt(i).Caption].SetOrdinal(i);
}
Throwing the contents into a dictionary will lose any sorting you may have had. Dictionaries are unordered collections.

The cleanest way to deal with this really is to implement your own custom comparer to compare the columns and reset their order based on the ordering.

I believe this would be more or less logically equivalent:

public class MyColumnComparer : Comparer&lt;DataColumn&gt;
{
    static Regex re = new Regex(@"[^\(\)][^\(]*\((\d{2}/\d{4})\).*");
    public override int Compare(DataColumn x, DataColumn y)
    {
        // a regular expression might be overkill here but it will be easier to maintain
        var xMatch = re.Match(x.Caption);
        var yMatch = re.Match(y.Caption);

        // both did not contain the pair
        if (!xMatch.Success &amp;&amp; !yMatch.Success)
        {
            // use original ordering
            return x.Ordinal.CompareTo(y.Ordinal);
        }

        // one contained the pair
        if (xMatch.Success != yMatch.Success)
        {
            return yMatch.Success ? -1 : 1;
        }

        // both contains a pair
        var xDate = DateTime.ParseExact(xMatch.Groups[1].Value, "MM/yyyy",
            CultureInfo.InvariantCulture);
        var yDate = DateTime.ParseExact(yMatch.Groups[1].Value, "MM/yyyy",
            CultureInfo.InvariantCulture);
        return xDate.CompareTo(yDate);
    }
}




static void ProcessTable(DataTable table)
{
    var sortedColumns = table.Columns
        .Cast&lt;DataColumn&gt;()
        .OrderBy(col =&gt; col, new MyColumnComparer())
        .ToList();
    var index = 0;
    foreach (var column in sortedColumns)
        column.SetOrdinal(index++);
}