Nhibernate and the design class
Let's say I have an Employee class and a Sales class.
Now tell me that I want to create a report page that displays all of the sales information for a given Employee.
When I return the collection, should I define a new class for the returned colllection?
Because I don't want to return ALL columns / properties for the Employee and Sales classes.
I need a base subset from each class / entity (basically this is a 1: 1 map for my Employee and Sales tables).
NHibernate can accomplish exactly this by using the Select New syntax, which loads the specified list of fields into your custom query result object. It calls the constructor that matches your requested fields. eg.
SELECT NEW EmployeeSalesSummary(e.Id, e.Name, SUM(s.SaleValue) TotalSales)
FROM Employee e
JOIN etc etc
More complete syntax example here
a source to share
I need you to pass your result. This is in the same process, say on a server, you don't need any special class because you can use lazy loading. You are configuring NHibernate to only load the referenced objects when you access them.
If you are sending the result over the wire, it is different because you need to serialize the data and require all properties to be completed. This is not really a NHibernate issue, it is your server frontend issue. Then you need a special DTO (Data Transfer Object) that only includes the data the client needs.
Edit:
I think you want lazy loading. There are two different types of lazy loading. Lazy loading of collections and lazy loading of references to individual objects.
Example:
class Employee
{
// make everything virtual to allow NH to build a proxy
public virtual string name { get; set; }
// will be lazy loaded
public virtual IList<Customers> Customers { get; private set; }
public virtual Employee Boss { get; set; }
}
Mapping
<!-- lazy=true is actually default -->
<class name="Employee" lazy="true">
<property name="Name"/>
<property name="Boss"/>
<!-- lazy=true is actually default -->
<bag name="Customers" type="Employee" lazy="true">
<key column="Employee_FK"/>
<one-to-many class="Employee" />
</bag>
</class>
Sample code
using (ISession session = CreateSession())
using (ITransaction trx session.CreateTransaction())
{
// get a instance of an employee
// the boss and the customers are not loaded until now
Employee emp = session.Get<Employee>(empid);
// emp.Boss is a proxy. This is a subclass of employee
// generated by NH that implements the lazy loading
// this loads the boss' data
if (emp.Boss.Name == "gogogurt")
{
// this is your employee
}
// this loads the Customers
if (emp.Customers.Count == 0)
{
HumanResources.Fire(emp);
}
trx.Commit();
}
// outside the session you cannot access the lazy
// loaded properties.
a source to share
I don't quite understand your question, but the design should be as simple as the Employee and Sale class. On sale might be an attribute employee, and NHibernate might have a many-to-one definition. When you select an employee, simply make an HQL query or criteria to return objects A sale that has an employee matches the employee you selected.
If it is customary for an employee to receive all of their sales, you may be inversely associated with an employee with a sales collection and be lazy to avoid performance issues.
In both cases, you don't need a special class
a source to share
If I understand your question correctly, this is what you want.
you only need some fields from Employee and some highlighted field from Sales.
The simplest is to only display the fields you need in the hbm mapping file.
for example: If you only want the employee ID and name, then just match them in the hbm files.
I apologize if I misunderstood the question.
a source to share
I'm not entirely sure if this answers your question, but if you just want to return certain properties, you can use Projection. Or perhaps you want to use query-only properties, as Ayende describes in NHibernate's Query-Only Properties ' - although that's for associations in general. Or there's also NHibernate Filters , which returns a subset of records. Or maybe a combination of them.
a source to share
Nod - read on lazy loading ( link text ) - essentially there is no cost on the server side to load an object entirely by a collection member. If you are navigating to something outside of the server, the "best practice" these days is not really a DTO, but rather uses a mapped superclass that has a subset of the fields you are interested in.
Then, make you a domain object of a subclass of that superclass, with additional constant fields. To go back to the page, just to the parents - and by serialization, you get exactly what you need.
a source to share