Skip to main content
Home  › ... Razor

LINQ Tutorials

Tutorial HomeLINQ

Initial Code

The following code runs at the beginning and creates some variables/services used in the following samples.

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

Show only books of Awarded Authors #1

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

Output

  1. Hitchhikers Guide to the Galaxy with Hugo Award (1 awards)
  2. Phishing for Phools with Nobel Peace Prize (1 awards)
@{
  // this keeps all books whose authors have awards
  var booksWithAwardedAuthors = books
    .Where(b => AsList(b.Authors as object).Any(a => a.Awards.Count > 0));
}
<ol>
  @foreach (var book in booksWithAwardedAuthors) {
    var awards = AsList(book.Authors as object).SelectMany(a => AsList(a.Awards as object));
    <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.

Output

  1. Good Omens
  2. The Last Continent
@{
  var otherBooks = books.Where(b => !booksWithAwardedAuthors.Contains(b as object));
}
<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:

Output

  • 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 => (AsList(b.Authors as object).Any(a => a.Awards.Count > 0)));
}
<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 ToSic.Razor.Blade;
@using System.Linq;
<!-- unimportant stuff, hidden -->


<div @Sys.PageParts.InfoWrapper()>
  @Html.Partial("../shared/DefaultInfoSection.cshtml")
  <div @Sys.PageParts.InfoIntro()>
    <h2>Books.Authors.Awards, a List in a List in a List</h2>
  </div>
</div>

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


<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>

  @{
    // this keeps all books whose authors have awards
    var booksWithAwardedAuthors = books
      .Where(b => AsList(b.Authors as object).Any(a => a.Awards.Count > 0));
  }
  <ol>
    @foreach (var book in booksWithAwardedAuthors) {
      var awards = AsList(book.Authors as object).SelectMany(a => AsList(a.Awards as object));
      <li><strong>@book.Title</strong> 
        with @string.Join(",", awards.Select(a => a.Name)) (@awards.Count() awards) 
      </li>
    }
  </ol>



<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.Contains(b as object));
  }
  <ol>
    @foreach (var book in otherBooks) {
      <li><strong>@book.Title</strong></li>
    }
  </ol>



<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 => (AsList(b.Authors as object).Any(a => a.Awards.Count > 0)));
  }
  <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>



@* Footer *@
@Html.Partial("../Shared/Layout/FooterWithSource.cshtml", new { Sys = Sys })