假设我有一个Employee类和一个Sales类。
现在说我要创建一个包含报告的页面,显示给定员工的所有销售信息。
当我返回集合时,我是否必须为返回的colllection定义一个新类?
因为我不想返回Employee&的所有列/属性。销售课程。
我基本上需要每个类/实体的一个子集(基本上是地图1:1到我的表Employee和Sales)。
答案 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,而是使用具有您感兴趣的字段子集的映射超类。
然后,让你的域实体成为这个超类的子类,带有额外的可持久字段。要传回一个页面,只需要对父母进行说明 - 并且在序列化时,您将得到您正在追求的内容。