Salesforce can give some pretty unhelpful errors at time. This one isn't the clearest, but if you pause for a moment and take a good look at it, it starts to make sense.
Besides the line number, this is the most important part of the error:
must be a concrete SObject: List
So somewhere, on that line, Salesforce is expecting an
SObject, but you're giving Salesforce a
We know it's on line 4. A SOQL query returns a
List, and you're storing the result in a
List, so there's no problem there (you actually don't need to use the
List constructor here, or do any casting for that matter, but that's beside the point).
The only other place on line 4 that can be causing your error is this:
where name in :b.account__c
If we take a look at the lines above,
b is defined as a
List<Book__c>. This fits the error that you're getting.
b is a
List, but using dot notation to reference a field is something that needs to be done on an
Your list stored in
b does contain
Book__c records (
Book__c is also an
SObject), so to be able to access the
Account__c field, you need access to one of the actual records in your list (for which you'd use
[<some integer>] or
At the very least (and I do emphasize that this is the very least you could do), to make this work, you'd do the following
// I've omitted the rest of the query for brevity
// Notice how we use square brackets before trying to reference the field
// Apex is 0-indexed, meaning the first item in the array is at index 0 (instead of 1)
where name in :b.account__c];
Keith C's answer goes over better practices for accomplishing what you're looking to do.