using System.Collections.Generic;
public int BookId { get; set; }
public string Title { get; set; }
public int BookId { get; set; }
public DateTime CheckedOutOn { get; set; }
public DateTime? ReturnedOn { get; set; }
public DateTime DueOn { get; set; }
public class BookViewModel {
public int BookId { get; set; }
public string Title { get; set; }
public bool IsAvailable { get; set; }
public DateTime? AvailableOn { get; set; }
public static void Main()
var books = new List<Book> {
new Book { BookId = 1, Title = "Book 1" },
new Book { BookId = 2, Title = "Book 2" },
new Book { BookId = 3, Title = "Book 3" }
var loans = new List<BookLoan> {
new BookLoan { BookId = 1, CheckedOutOn = new DateTime(2016, 1, 3), DueOn = new DateTime(2016, 2, 4), ReturnedOn = new DateTime(2016, 2, 3)},
new BookLoan { BookId = 1, CheckedOutOn = new DateTime(2016, 6, 9), DueOn = new DateTime(2016, 7, 4), ReturnedOn = null },
new BookLoan { BookId = 2, CheckedOutOn = new DateTime(2016, 4, 5), DueOn = new DateTime(2016, 5, 3), ReturnedOn = new DateTime(2016, 5, 23)},
new BookLoan { BookId = 2, CheckedOutOn = new DateTime(2016, 6, 1), DueOn = new DateTime(2016, 8, 4), ReturnedOn = new DateTime(2016, 7, 5)},
new BookLoan { BookId = 3, CheckedOutOn = new DateTime(2016, 1, 9), DueOn = new DateTime(2016, 2, 4), ReturnedOn = null }
var viewModel = from book in books
join loan in loans.Where(x => !x.ReturnedOn.HasValue) on book.BookId equals loan.BookId into result
from loanWithDefault in result.DefaultIfEmpty()
select new BookViewModel {
IsAvailable = loanWithDefault == null,
AvailableOn = loanWithDefault == null ? (DateTime?) null : loanWithDefault.DueOn
Console.WriteLine("Available: ");
viewModel.Where(x => x.IsAvailable).ToList().ForEach(x => Console.WriteLine(x.Title));
Console.WriteLine("\nUnavailable: ");
viewModel.Where(x => !x.IsAvailable).ToList().ForEach(x => Console.WriteLine(x.Title + " - available " + x.AvailableOn));