2009-05-24 2 views
1

Скажите, что у меня есть класс Employee и класс Sales.nhibernate и класс дизайна

Теперь скажите, что я хочу создать страницу с отчетом, отображающую всю информацию о продажах для данного Сотрудника.

Когда я верну коллекцию, должен ли я определить новый класс для возвращаемого результата?

Потому что я не хочу возвращать ВСЕ столбцы/свойства для Employee & Продажи.

Мне необходимо подмножество из каждого класса/объекта (в основном это карта 1: 1 для моих таблиц Employee and Sales).

+0

Я думаю, что вам нужна ленивая загрузка. Я добавил пример моего ответа. –

ответ

0

зависит от того, где вы должны передать свой результат. Это в том же процессе, скажем, на сервере, вам не нужен какой-либо специальный класс, потому что вы можете использовать ленивую загрузку. Вы настраиваете NHibernate только для загрузки ссылочных объектов при доступе к ним.

Если вы отправляете результат по проводу, он отличается, потому что вам необходимо сериализовать данные и потребовать, чтобы все свойства были заполнены. На самом деле это не проблема NHibernate, это проблема вашего интерфейса сервера. Тогда вам понадобится специальный DTO (объект передачи данных), который включает только те данные, которые необходимы клиенту.

Edit:

Я думаю, что вам нужно отложенной загрузки. Существует два разных типа ленивой загрузки. Ленивая загрузка коллекций и ленивая загрузка ссылок на отдельные объекты.

Пример:

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> 

Пример кода

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. 
+0

его веб-приложение. Пользователь просматривает страницу/user/salesreport. Данные хранятся в sqlserver. – 2009-05-24 21:48:05

+0

У меня нет опыта работы с веб-приложениями .NET. Нужно ли сериализовать данные? Вы все еще находитесь в пределах сеанса при создании страницы? –

0

Я не полностью понимаю ваш вопрос, но дизайн должен быть столь же просто, как Сотрудник и Продажа класс. Продажа может иметь сотрудника атрибута, а в NHibernate - определение множества-к-одному. Когда вы выбираете сотрудника, просто сделайте запрос HQL или критерии для возврата объектов Продажа, которые имеют сотрудник соответствует выбранному вами сотруднику.

Если принято, чтобы работник получил все свои продажи, вы можете получить обратную ассоциацию, имеющую сотрудника с коллекцией продаж, и сделать ее ленивой, чтобы избежать проблем с производительностью.

В обоих случаях вам не нужны какие-либо специальные класс

1

NHibernate может сделать именно это, используя «Выберите New» синтаксис, который загружает указанный список полей в пользовательский объект результата запроса. Он вызывает конструктор, который соответствует вашим запрошенным полям. например

SELECT NEW EmployeeSalesSummary(e.Id, e.Name, SUM(s.SaleValue) TotalSales) 
FROM Employee e 
JOIN etc etc 

Более подробный пример синтаксис is here

+0

Похоже, что пример синтаксического примера мертв. –

+0

@ Daniel, исправленный. –

-2

Нода - Читайте на отложенной загрузке (link text) - по существу, на стороне сервера, нет затрат на загрузку всего элемента-зоре хозяйствующего субъекта. Если вы переходите к чему-то за пределами сервера, то «лучшая практика» в наши дни на самом деле не является DTO, а использует сопоставленный суперкласс, у которого есть подмножество интересующих вас полей.

Затем сделайте так, 're domain entity - подкласс этого суперкласса с дополнительными устойчивыми полями. Чтобы вернуться к странице, просто к родителям - и по сериализации, вы получите именно то, что вам нужно.

+0

Хм, как должен работать этот суперкласс? Когда вы вывели класс и вы получаете производный класс из базы данных, бесполезно ссылаться на него как на базовый класс. Экземпляр всегда относится к типу подкласса со всеми дополнительными полями. –

+0

Извините - я не хотел, чтобы это казалось магией - я, вероятно, должен был расшириться. Вы по-прежнему используете DTO, но вместо того, чтобы определять объект DTO и Entity как полностью отдельный, у вас есть вышеупомянутая иерархия классов и есть метод в классе Entity, чтобы создать новый экземпляр суперкласса (тот, который ограничен поля). Я не предлагаю, чтобы кастинг суперкласса собирался «удалять» загруженные поля - это было бы глупо :) – Chaos

+1

Я бы предложил использовать интерфейсы. базовые классы всегда «страшные». Есть только свойства, поэтому «реализация» на самом деле не является чем-то сложным, вам нужно наследовать. –

0

Если я правильно понял ваш вопрос, это то, что вы хотите.

Вам нужны только некоторые поля от Employee & какое-то выбранное поле из отдела продаж.

Проще всего сделать, это отобразить только те поля, которые требуются в файле отображения hbm.

например: Если вам нужен только идентификатор & Имя сотрудника, а затем сопоставлять его только в файлах hbm.

Извинения, если я понял вопрос неправильно.

0

Я не совсем уверен, ответит ли это на ваш вопрос, но если вы просто хотите вернуть определенные свойства, вы можете использовать Projection. Или, возможно, вы хотите использовать свойства только для запроса, как описывает Айенде в 'NHibernate Query-Only Properties' - хотя это для ассоциаций вообще. Или же есть NHibernate Filters, который возвращает подмножество записей. Или, может быть, сочетание этих.

Смежные вопросы