Нибернат и дизайн класса - PullRequest
1 голос
/ 25 мая 2009

Скажем, у меня есть класс Employee и класс Sales.

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

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

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

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

Ответы [ 6 ]

1 голос
/ 25 мая 2009

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

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

Более полный пример синтаксиса здесь

0 голосов
/ 16 июля 2009

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

0 голосов
/ 27 мая 2009

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

вам нужны только некоторые поля из Employee и несколько выбранных полей из Sales.

Самое простое, что нужно сделать, это отобразить только те поля, которые вам нужны в файле отображения hbm

Например: если вам нужны только идентификатор и имя сотрудника, сопоставьте их только с файлами hbm.

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

0 голосов
/ 25 мая 2009

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

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

0 голосов
/ 25 мая 2009

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

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

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

0 голосов
/ 25 мая 2009

Я зависит от того, куда вы должны передать свой результат. В том же процессе, скажем, на сервере, вам не нужен какой-то специальный класс, потому что вы можете использовать ленивую загрузку. Вы настраиваете 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; }  
}

Отображение

<!-- 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. 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...