check if value already exists

If you are allowed to use LINQ, try using the below code:

bool exists = books.Any(b => (b.Value != null && b.Value.title == "current title"));

If you're not using the book title as the key, then you will have to enumerate over the values and see if any books contain that title.

foreach(KeyValuePair<string, book> b in books) // or foreach(book b in books.Values)
{
    if(b.Value.title.Equals("some title", StringComparison.CurrentCultureIgnoreCase))
        return true
}

Or you can use LINQ:

books.Any(tr => tr.Value.title.Equals("some title", StringComparison.CurrentCultureIgnoreCase))

If, on the other hand, you are using the books title as the key, then you can simply do:

books.ContainsKey("some title");

books.ContainsKey("book name");