Assuming you have database tables and entities that are in 3rd normal form, you will have quite a number of child tables and "lookup" tables. For example, you may have a Person class that has a collection of Addresses, Phones, etc. The Address and Phone classes have references to "lookup" entities like State, Country, ZipCode, AddressType, PhoneType, etc.
For particular use cases, you will probably want to see a "flattened" view of the data -- e.g. a record that contains a person, their office address, their office phone, their mobile phone, their email address, etc. and also see descriptions (or other important values) from the "lookup" entities. To do this, you should make a class that takes all the entities it uses to produce the "flattened" view as constructor arguments:
Code:
public class PersonView
{
private Person _person;
private Address _workAddress;
private Phone _officePhone;
private Phone _moblePhone;
private Email _officeEmail;
...
public string FirstName
{
get { return (this._person != null ? this._person.FirstName: ""); }
set { ... }
}
public string LastName
{
get { return (this._person != null ? this._person.LastName: ""); }
set { ... }
}
public string WorkAddressLine1
{
get { return (this._workAddress != null ? this._workAddress.Line1: ""); }
}
public string WorkAddressCountryName
{
get { return this._workAddress != null && this._workAddress.Country != null ? this._workAddress.Country.Name : ""); }
}
...
public PersonView(Person person, Address officeAddress, Phone officePhone, Phone mobilePhone, Email officeEmail, ...)
{
this._person = person;
this._workAddress = workAddress;
...
}
}
Then in an HQL query, you can do this:
Code:
SELECT new PersonView(person, officeAddress, officePhone, mobilePhone, officeEmail ...)
FROM Person AS person
LEFT JOIN Person.Addresses AS workAddress
LEFT JOIN Person.Phones AS officePhone
LEFT JOIN Person.Phones AS mobilePhone
LEFT JOIN Person.Emails AS officeEmail
...
WHERE officeAddress.AddressType.Id = 'Office'
AND officePhone.PhoneType.Id = 'Office'
...
The point of all this is that your mapped entities should remain normalized, and any "denormalized views" that you need for particular use cases should be classes composed of your entities.