nhibernate和类设计

时间:2009-05-24 21:37:28

标签: nhibernate

假设我有一个Employee类和一个Sales类。

现在说我要创建一个包含报告的页面,显示给定员工的所有销售信息。

当我返回集合时,我是否必须为返回的colllection定义一个新类?

因为我不想返回Employee&的所有列/属性。销售课程。

我基本上需要每个类/实体的一个子集(基本上是地图1:1到我的表Employee和Sales)。

6 个答案:

答案 0 :(得分:1)

NHibernate可以使用“选择新”语法完成此操作,该语法将指定的字段列表加载到自定义查询结果对象中。它调用与查询字段匹配的构造函数。 e.g。

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

语法is here

的更全面的示例

答案 1 :(得分:0)

我取决于你必须将结果传递给的地方。它是在同一个进程中,比如在服务器中,你不需要任何特殊的类,因为你可以使用延迟加载。您将NHibernate配置为仅在访问时加载引用的实体。

如果通过网络发送结果,则不同,因为您需要序列化数据并需要完成所有属性。这实际上不是NHibernate的问题,它是您的服务器接口的问题。然后,您需要一个特殊的DTO(数据传输对象),它只包含客户端所需的数据。

修改

我认为你需要的是延迟加载。有两种不同的延迟加载。延迟加载集合和延迟加载对单个实体的引用。

示例:

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. 

答案 2 :(得分:0)

我不完全理解您的问题,但设计应该像 Employee Sale 类一样简单。 Sale 可能具有属性employee,并且在NHibernate中具有多对一映射定义。当您选择员工时,只需进行HQL查询或条件即可返回员工等于您所选员工的 Sale 对象。

如果让员工获得所有销售额是很常见的,那么您可能会产生反向关联,让员工拥有一系列销售,并使其懒惰以避免性能问题。

在这两种情况下,您都不需要任何特殊的课程

答案 3 :(得分:0)

如果我理解你的问题,这就是你想要的。

您只需要Employee&amp ;;来自Sales的一些选定字段。

最简单的方法是仅映射hbm映射文件中所需的那些字段。

例如:如果你只需要Id&amp;员工的姓名,然后只将那些映射到hbm文件中。

道歉,如果我理解错误的话。

答案 4 :(得分:0)

我不确定这是否会回答您的问题,但如果您只想返回某些属性,则可以使用投影。或许你想使用Ayende在'NHibernate Query-Only Properties'中描述的仅查询属性 - 尽管这通常用于关联。或者,还有NHibernate Filters返回记录的子集。或者也许是这些的组合。

答案 5 :(得分:-2)

点头 - 阅读延迟加载(link text) - 实际上,在服务器端,加载实体的整个成员集是没有成本的。如果您要转到服务器之外的某些东西,那么这些天的“最佳实践”实际上不是DTO,而是使用具有您感兴趣的字段子集的映射超类。

然后,让你的域实体成为这个超类的子类,带有额外的可持久字段。要传回一个页面,只需要对父母进行说明 - 并且在序列化时,您将得到您正在追求的内容。