If you're looking for dynamic runtime polymorphism, have you checked out the dynamic
keyword in C# 4.0? If it meets your need, I would imagine it's a lot simpler than what you're trying to do.
See Rob Conery's work with Massive, where he demonstrates how to build a dynamic ORM in C# 4.0 using 400 lines of code.
Creating proxy classes at runtime is not exactly an unprecedented technique, see Castle Dynamic Proxy and FasterFlect. If your only worry is that you're breaking some architectural austronaut's rule book, I'm not sure it's worth worrying about.
OOP isnt meant to just plain "seperate things". It's more about organization and intent and reusability (when appropriate). Take a look at Domain Driven Design (DDD). Specifically, identifying where your "Value Objects" are, your "Entities" are and which "Services / Factories / Repositories" are needed to support them to get you where you need to be.
In answer to your qeustion:
Would I create a class for building, level, room and item with the following structure
-Yes, it seems those would be your Models
building can have 1 or many level objects held in an array level can
have 1 or many room objects held in an array room can have 1 or many
item objects held in an array
-That sounds right, the Building then would be your Entity, because each building is unique and has a distinct existance, as opposed to an "item" or "room" which have a clearly defined value, but no distict existance other than it's uniqueness to who owns it.
and mappers for each class with higher level mappers using the child
mappers to populate the arrays (either on request of the top level
object or lazy load on request)
-This is where you're going to want expand a bit. Basically, you're going to want to create repositories / factories which will be able to fetch and load your "entities" with data. This might be what you are referring to as "Mappers", but when I hear mappers I think of "Active Record's". which are objects which save and load themselves and pretty much are 1-1 with the database. With that concept, breaking out the core "properties" per intent can become messy (it probably works for some).
Here are some good resources which should aid in your development.
Check out Domain Driven Design Concepts, there are a few Moguls out there which you'll come across very quickly which will offer you detailed insight into the theories at hand. Here are some links to get you started:
this is a pretty brief explanation:
http://mattpeters.net/2009/03/24/domain-driven-design-part-1-introduction-and-entities/
this one has the cool domain name and turns out to be a great resource:
http://domaindrivendesign.org/
Best Answer
It's fairly common to include the ID, but it's also common to use dictionaries, i.e. the data structures where each object is associated with its ID in a way that you can easily retrieve this object knowing the corresponding ID, but the object doesn't know it.
For example, if you're creating an API with two methods:
http://api.example.com/products/
Loads the list of IDs of products.
http://api.example.com/product/452/
Loads a product of ID 452.
Then you don't need to resend the ID 452 in the JSON response of the second request. The user of the API already knows the ID.