LINQ in Action - LINQ Book & News

  • LINQ or Lync?

    There's a new "link" from Redmond. It's not LINQ this time, but Lync.
    Isn't it great to have two names colliding in the Microsoft world?

    Is someone working on LINQ to Lync?

  • Object databases for .NET with LINQ support

    More and more database management systems offer built-in support for LINQ.

    I've just tested some lightweight object database engines for .NET. See this post on my blog.

  • Hex Dump using LINQ (in 7 lines of code)

    Eric White has posted an interesting LINQ query on his blog that shows how to create a Hex Dump in something like 7 lines of code.

    Of course, this is not production grade code, but it's another good example that demonstrates the expressiveness of LINQ.

    Here is the code:

    byte[] ba = File.ReadAllBytes("test.xml");
    int bytesPerLine = 16;
    string hexDump = ba.Select((c, i) => new { Char = c, Chunk = i / bytesPerLine })
        .GroupBy(c => c.Chunk)
        .Select(g => g.Select(c => String.Format("{0:X2} ", c.Char))
            .Aggregate((s, i) => s + i))
        .Select((s, i) => String.Format("{0:d6}: {1}", i * bytesPerLine, s))
        .Aggregate("", (s, i) => s + i + Environment.NewLine);
    Console.WriteLine(hexDump);

    Here is a sample output:

    000000: FF FE 3C 00 3F 00 78 00 6D 00 6C 00 20 00 76 00
    000016: 65 00 72 00 73 00 69 00 6F 00 6E 00 3D 00 22 00
    000032: 31 00 2E 00 30 00 22 00 20 00 65 00 6E 00 63 00
    000048: 6F 00 64 00 69 00 6E 00 67 00 3D 00 22 00 75 00
    000064: 3E 00

    Eric White reports that he typically notices that declarative code is only 20% as long as imperative code.

  • New LINQ tools category on SharpToolbox.com

    I've just moved the LINQ tools referenced on SharpToolbox.com to a new dedicated LINQ category.
    20 tools and providers are listed for the moment. I'll add more shortly.

    See Jim's blog for more resources.

  • LINQ in Action is now available in Chinese (LINQ实战) and in English in India

    After English, German, Spanish, and Portuguese, LINQ in Action is now available in Chinese (中文).

    The title is LINQ实战. The publisher is 人民邮电出版社 (Posts & Telecom Press). The book is also available on Amazon.cn/joyo and several other bookstores.

    In addition to all the translations, LINQ in Action has been republished in English in India by DreamTech Press.

  • LINQ in Action XML samples now in LINQPad too

    After we published the code samples for LINQ in Action's first chapters in LINQPad a few weeks ago, the samples of three more chapters have just been added. These chapters cover LINQ to XML. Thanks Jim for doing the additional conversion.

    The code samples for chapters 1 to 11 are now available. Read the original announcement to learn how to download and use these samples. A new download is enough to get the update.

  • LINQ in Action samples in LINQPad

    LINQPad logo

    Do you know LINQPad? It's a really simple but great tool for testing LINQ queries. Not only that, but it can be used to test all kinds of C# and VB code snippets.

    Another great thing about LINQPad is that it comes with code samples. Until now the integrated code samples came from the C# 3.0 in a Nutshell book. Joe Albahari, author of LINQPad and C# 3.0 in a Nutshell, has opened LINQPad so that code samples from other books can be integrated into LINQPad. Thanks Joe for this opportunity!

    We worked with Joe to integrate LINQ in Action's code samples into LINQPad. The result is that in addition to being available as Visual Studio solutions and projects, you can now run our code samples directly from LINQPad. This makes it very easy to explore LINQ's features with instant "code and play".

    To install LINQ in Action's code samples in LINQPad, all you have to do is click on the "Download more samples..." link:

     

    You'll see LINQ in Action proposed as one of the LINQPad-enabled books (the only one at the moment, in fact):

     

    Once you've clicked on "Download full code listings into LINQPad", you should see the C# and VB samples grouped by chapter:


    Currently, chapters 1 to 8 are available. We'll integrate the remaining code samples soon.

    Have fun with LINQ!

  • ForEach debate continued

    Eric Lippert, whose blog you shouldn't miss, adds his own arguments to the debate about whether using a ForEach extension method instead of foreach is a good idea or a bad one.

    I don't see a definitive answer to the question. All the arguments given here and elsewhere are good, but in the end, it's up to you to decide what you prefer to do.
    Read the posts and the comments to make up your own mind.

  • LINQ em Ação, LINQ in Action in Portuguese

    LINQ em AçãoAfter English, German and Spanish, LINQ in Action is now available em Português.

    The title is LINQ em Ação. The publisher is Editora Ciência Moderna.

  • LINQ in Action in Spanish

    Today I had the pleasure to receive a copy of LINQ in Action translated in Spanish. This came a bit unexpected, but it's great!

    LINQ in Action already existed in German (LINQ im Einsatz), and I know that other translations should be published soon. The Chinese version is the next one expected, I believe.

    The Spanish version of the book is published by Anaya Multimedia. The title of the book is simply... "LINQ"!

    ¡Espero que disfruten la lectura de este libro!

  • LINQ Deep Dive: great LINQ tips

    Zeeshan Hirani who already offered us a 500-page Entity Framework learning guide, now publishes great LINQ tips in the first part of his LINQ Deep Dive articles. These tips are not the usual introductions to LINQ features you can find elsewhere. You can tell that they come from someone who lives in the trenches. I learnt very interesting features and best practices I didn't know about.

    1. Apply filters before a join to improve query performance
    2. Filter LINQ queries using object reference comparison
    3. Apply aggregates to empty collections in LINQ to SQL queries
    4. Delay loading a property in LINQ to SQL
    5. Use table-valued functions with eager loading turned on
    6. Put joins in the correct order in a LINQ to Objects query
    7. Compose a LINQ query inside a loop

    LINQ Deep Dive: Part I, Tips for Delving in to LINQ

  • ForEach or not ForEach, that is the question

    In LINQ in Action, we discuss about the missing ForEach query operator. This is in Chapter 5 "Beyond basic in-memory queries", more precisely in section 5.2.2. There, we indicate that Eric White suggested this operator in his functional programming tutorial, although I'm not able to find the exact reference at the moment in this tutorial.

    Since then, a lot of people have been asking for ForEach. This can be seen on Kirill Osenkov's blog, where you'll find links to discussions about whether ForEach is good or bad.
    I don't know if we're going to see ForEach appear in .NET. Anyway, it's not very difficult to write your own:

    public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
    {
      if (source == null)
        throw new ArgumentNullException("source");
      if (action == null)
        throw new ArgumentNullException("action");

      foreach (var item in source)
        action(item);
    }

  • Converting LINQ queries from query syntax to method/operator syntax

    Yesterday a reader of the LINQ in Action book posted an interesting challenge on the book's forum. It's interesting enough to be reposted it here.

    The request was to convert a LINQ query expression (query syntax) to a query operator call chain (method syntax or dot notation). The original query was the following one:

    from publisher in SampleData.Publishers
    join book in SampleData.Books on publisher equals book.Publisher into publisherBooks
    from book in publisherBooks.DefaultIfEmpty()
    select new
    {
      Publisher = publisher.Name,
      Book = book == default(Book) ? "(no books)" : book.Title
    };

    This query comes from LINQ in Action. In chapter 4 more precisely, where we cover grouping and joins.

    Converting LINQ queries is an interesting exercise because it's not always easy to find the solution but you learn a lot in the process. Often, you'll have to use "tricks". Here the tricks are based on the use of anonymous types. Side note: this is also what you'd use to translate the let keyword.

    Here is the solution I gave:

    SampleData.Publishers
      .GroupJoin(SampleData.Books,
        publisher => publisher, book => book.Publisher,
        (publisher, publisherBooks) => new { Publisher = publisher, PublisherBooks = publisherBooks })
      .SelectMany(
        group => group.PublisherBooks.DefaultIfEmpty<Book>(),
        (group, book) => new {
          Publisher = group.Publisher.Name,
          Book = (book == null) ? "(no books)" : book.Title
        });

    Not as easy to read as your original query, don't you think? See my previous post about Query syntax vs. Method syntax to decide which syntax is best for you.

    "How did he manage to convert the query," you may be wondering... Well, even if I know the tricks, the easiest is to use .NET Reflector to decompile the IL.
    If you specify ".NET 3.5" for the Optimization option, you'll see the query expression. But if you specify ".NET 2.0", you'll see something that looks close to the above query. You'll have to replace the anonymous methods with lambda expressions and change the name of the anonymous parameters to make the code somewhat more readable, though.

    As usual, Reflector is your best friend. It reveals a lot of secrets ;-)

    Update: Joe Albahari, of LINQPad fame, suggested other solutions:

    1) Calling .ToString() on the query's expression will work just fine if you add AsQueryable() to the first sequence: from publisher in SampleData.Publishers.AsQueryable() join book...
    2) If you use LINQPad to run the query, you'll notice it shows lambda translations for all IQueryable-based queries. LINQPad uses its own expression visitor so the result is much more readable than simply calling ToString on the expression.

  • IQToolkit, building your own LINQ IQueryable provider

    Matt Warren, who provides the most detailed HOWTO for creating your own LINQ IQueryable provider, has now published a dedicated toolkit on CodePlex:

    IQToolkit is essential if you are building your own LINQ IQueryable provider. It contains common tools and source code you can apply to your own project.
    In the toolkit you will find useful techniques for manipulating LINQ expression trees, implementing IQueryable providers, and a host of extensible components for building providers that target translation of LINQ expressions into SQL like languages.

    http://www.codeplex.com/IQToolkit

    Creating a LINQ provider is not a walk in the park, but at least if you have to, you have everything you need at hand.

  • Using the Select LINQ query operator with indexes

    Yesterday, Fred asked me if I could help him to convert C# code to LINQ. The solution may not obvious to find unless you know LINQ well. I will reproduce here the solution I gave Fred. Whether the LINQ version of the code is easier to read than the original one is arguable. The purpose here is more to show LINQ's Select query operator in action.

    Here is the original code:

    int CountCorrectChars(string proposedValue, string correctValue)
    {
      int correctCount = 0;
      for (int i = 0; i < proposedValue.Length && i < correctValue.Length; i++)
        if (proposedValue[i] == correctValue[i])
          correctCount++;
      return correctCount;
    }

    Here is the LINQ version that I suggested:

    int CountCorrectChars(string proposedValue, string correctValue)
    {  
    return correctValue
        .Select((testChar, index) => new { Character = testChar, Index = index })
        .Count(testChar => (testChar.Index < proposedValue.Length)
    && (testChar.Character == proposedValue[testChar.Index]));
    }

    As you can see, the LINQ version is not so easy to understand and is verbose. Of course, we could use shorter names, but that wouldn't change the complexity of the query. The LINQ version is not as good in terms of performance either... So, should we use LINQ or not? My point here is that LINQ is not a "one size fits all" solution. You should use it wisely and avoid complexifying code by choosing always to use LINQ.

    What's interesting in this example, is also simply the use of Select with a two-parameter lambda expression. You may know the version of Select that takes a single-parameter lambda well, but its counterpart is less known (and used).

    This is something that we cover in LINQ in Action in section 4.4.2. Here is what we write there, which gives another example of Select in action:

    The Select and SelectMany operators can be used to retrieve the index of each element in a sequence. Let’s say we want to display the index of each book in our collection before we sort them in alphabetical order:

    index=3         Title=All your base are belong to us
    index=4         Title=Bonjour mon Amour
    index=2         Title=C# on Rails
    index=0         Title=Funny Stories
    index=1         Title=LINQ rules

    Here is how to use Select to achieve that:

    Listing 4.15    Code-behind for the first ASP.NET page    (SelectIndex.csproj)
    var books =
      SampleData.Books
        .Select((book, index) => new { index, book.Title })
        .OrderBy(book => book.Title);
    ObjectDumper.Write(books);

    This time we can’t use the query expression syntax because the variant of the Select operator that provides the index has no equivalent in this syntax. Notice that this version of the Select method provides an index variable that we can use in our lambda expression (precision not in the book: its not the name "index" that is important. You can use another name if you want. What makes the difference is that the lambda expression takes two parameters). The compiler automatically determines which version of the Select operator we want to use just by looking at the presence or absence of the index parameter. Notice also that we call Select before OrderBy. This is important to get the indices before the books are sorted, not after.

    ...One more tool in your toolbox. Now, use it wisely.

    Update: Mark Sowul suggests a simpler solution:

    return correctValue.Where((testChar, index) => index < proposedValue.Length && testChar == proposedValue[index]).Count();
    Somehow I missed that Where overload.

     

More Posts Next page »