Skip to main content

LINQ Tutorials

Tutorial Home

Show only books of Awarded Authors #1

This example first gets book, checks the authors and checks if they have awards with LINQ Any().

  1. Hitchhikers Guide to the Galaxy with Hugo Award (1 awards)
  2. Phishing for Phools with Nobel Peace Prize (1 awards)

@{
  var booksWithAwardedAuthors = books
    .Where(b => (b.Authors as Dynlist)
      // this gets all the awards and combines (flattens) the list
      .SelectMany(a => a.Awards as Dynlist) 
      .Any()
    );
}
<ol>
  @foreach(var book in booksWithAwardedAuthors) {
    var awards = (book.Authors as Dynlist).SelectMany(a => (a.Awards as Dynlist));
    <li><strong>@book.Title</strong> 
      with @string.Join(",", awards.Select(a => a.Name)) (@awards.Count() awards) 
    </li>
  }
</ol>

Now the list of books NOT in that list

And now the opposite list, so all books which don't contain one of the books with authors. It gets the "other" books by filtering the list to exclude the ones it found first. That demonstrates how to use Contains(x as object). The Contains(...) cannot work with dynamic, so we must tell it it's an object for it to work.

  1. Good Omens
  2. The Last Continent

@{
  var otherBooks = books
    .Where(b => !(booksWithAwardedAuthors as Dynlist)
      .Contains(b as object) // note: Contains() on dynamic objects needs 2sxc 9.42+ to work
    );
      
}
<ol>
  @foreach(var book in otherBooks) {
    <li><strong>@book.Title</strong></li>
  }
</ol>

Now the same using GroupBy

Now let's do the same, but using GroupBy to group by awarded authors and not-awarded authors:

  • Authors with Awards: True
    • Hitchhikers Guide to the Galaxy
    • Phishing for Phools
  • Authors with Awards: False
    • Good Omens
    • The Last Continent

@{
  var booksGroupedByAuthorAwards = books
    .GroupBy(b => ((b.Authors as Dynlist).SelectMany(a => a.Awards as Dynlist).Any()));
}
<ul>
  @foreach(var group in booksGroupedByAuthorAwards) {
    <li>
      Authors with Awards: @group.Key
      <ul>
        @foreach(var book in group) {
          <li>
            @book.Title
          </li>
        }
      </ul>
    </li>
  }
</ul>

Source Code of this file

Below you'll see the source code of the file. Note that we're just showing the main part, and hiding some parts of the file which are not relevant for understanding the essentials. Click to expand the code

@inherits Custom.Hybrid.Razor14
@using System.Linq;
@using Dynlist = System.Collections.Generic.IEnumerable<dynamic>;

<!-- unimportant stuff, hidden -->

@{
  var persons = AsList(App.Data["Persons"]);
  var books = AsList(App.Data["Books"]);
}

@Html.Partial("_header.cshtml")

<div class="row">
  <div class="col-lg-7">
    <h2>Books.Authors.Awards, a List in a List in a List</h2>
  </div>
  @Html.Partial("../shared/_DefaultInfoSection.cshtml")
</div>

<h3>Show only books of Awarded Authors #1</h3>
<p>This example first gets book, checks the authors and checks if they have awards with LINQ <code>Any()</code>. </p>

@{
  var booksWithAwardedAuthors = books
    .Where(b => (b.Authors as Dynlist)
      // this gets all the awards and combines (flattens) the list
      .SelectMany(a => a.Awards as Dynlist) 
      .Any()
    );
}
<ol>
  @foreach(var book in booksWithAwardedAuthors) {
    var awards = (book.Authors as Dynlist).SelectMany(a => (a.Awards as Dynlist));
    <li><strong>@book.Title</strong> 
      with @string.Join(",", awards.Select(a => a.Name)) (@awards.Count() awards) 
    </li>
  }
</ol>


<hr>


<h3>Now the list of books NOT in that list</h3>
<p>And now the opposite list, so all books which don't contain one of the books with authors. It gets the "other" books by filtering the list to exclude the ones it found first. That demonstrates how to use <code>Contains(x as object)</code>. The <code>Contains(...)</code> cannot work with <code>dynamic</code>, so we must tell it it's an object for it to work.</p>

@{
  var otherBooks = books
    .Where(b => !(booksWithAwardedAuthors as Dynlist)
      .Contains(b as object) // note: Contains() on dynamic objects needs 2sxc 9.42+ to work
    );
      
}
<ol>
  @foreach(var book in otherBooks) {
    <li><strong>@book.Title</strong></li>
  }
</ol>



<hr>

<h3>Now the same using GroupBy</h3>
<p>Now let's do the same, but using <code>GroupBy</code> to group by awarded authors and not-awarded authors:</p>

@{
  var booksGroupedByAuthorAwards = books
    .GroupBy(b => ((b.Authors as Dynlist).SelectMany(a => a.Awards as Dynlist).Any()));
}
<ul>
  @foreach(var group in booksGroupedByAuthorAwards) {
    <li>
      Authors with Awards: @group.Key
      <ul>
        @foreach(var book in group) {
          <li>
            @book.Title
          </li>
        }
      </ul>
    </li>
  }
</ul>



<!-- unimportant stuff, hidden -->