Nhibernate 映射hbm.xml

Nhibernate 映射hbm.xml,nhibernate,nhibernate-mapping,Nhibernate,Nhibernate Mapping,我有一个一对多的关系,但我只想得到一个实例来有一对一的关系 我有一类车辆,可能在其一生中有几个车主。我只想映射类以获取资产。有没有办法做到这一点 问题出在hbm.xml文件中。一辆车一生可能有几个车主,但我只想得到最后一个车主。我需要按VehicleId、ownerId和EndDate进行筛选。我想用资产填充vehicle.cs中的对象所有者 当我写入时:vehicleuv=vehicleulservice.searchvehicleue(id) 我想要v.车主必须包含最后一辆车的车主 我无法将

我有一个一对多的关系,但我只想得到一个实例来有一对一的关系

我有一类车辆,可能在其一生中有几个车主。我只想映射类以获取资产。有没有办法做到这一点

问题出在hbm.xml文件中。一辆车一生可能有几个车主,但我只想得到最后一个车主。我需要按VehicleId、ownerId和EndDate进行筛选。我想用资产填充vehicle.cs中的对象所有者

当我写入时:vehicleuv=vehicleulservice.searchvehicleue(id)

我想要v.车主必须包含最后一辆车的车主


我无法将车主ID存储在车辆表上,因为车主取决于日期。例如,我可以: 车主开始日期结束日期 1 1 04/04/2009 04/10/2009 1 2 05/10/2009无效

由于这个原因,我必须按EndDate筛选以获得资产

我有三张桌子:Vehicle、Owner和OwnerVehicle。问题是我必须在vehicle.cs中引用当前所有者。我不知道如何进行映射


任何帮助都将不胜感激。谢谢

一种简单的映射方法是将其转换为多对一关系,并将当前车主ID存储在车辆表上。我知道这可能是一个模式更改

其中一种方法是创建一个视图,该视图实质上是vehicle表,再加上它将提取当前所有者ID。这样,您就不必更改模式,然后可以映射到视图而不是表

我不确定在这种情况下定义自己的加载器是否有效,但这是一个需要进一步探索的选项

编辑 我理解你的预测。最简单的方法是修改模式和应用程序以添加此附加列。伪造此列的一种方法是使用视图。比如说

select vehicle.*, owner.ownerid
from vehicle
inner join owner 
  on owner.vehicleid=vehicle.vehicle
and owner.enddate is null 
我假设当前所有者的结束日期为空。现在将映射更改为映射到视图而不是表。是的,这是一个黑客,但它会工作

我假设您仍然需要在nHibernate中映射所有者?另一个选项是在所有者的类映射上添加一个where过滤器,以过滤结束日期为null的地方

另一个选项是加载所有所有者,并将定义当前所有者的业务规则推送到应用层。您的对象可能看起来像:

public Owner CurrentOwner
{
    get 
    {
        return _owners.Find(o=>o.EndDate==DateTime.Min); //Or null if your using a nullable datetime
     }
    set 
    {
        CurrentOwner.EndDate=DateTime.Now;
        _owners.Add(value);
    }
}

}

您可以在执行搜索时使用Criteria(或DetachedCriteria for Spring)对象来限制附加值。

我建议在业务层中维护此引用,并将其映射为多对一关系。我的意思是在代码中显式地设置这个引用。这还允许您直接查找当前车主的车辆

例如:

<class name="Vehicle">
  <map name=AllOwners" >
  ...
  </map>

  <many-to-one name="CurrentOwner" ...>
</class>

public class Vehicle
{
  IList<Owner> AllOwners { get; private set; }
  Owner CurrentOwner { get; set; }
}

public void SetNewOwner(Vehicle v, Owner o)
{
  v.AllOwners.Add(o);
  v.CurrentOwner = o;
}


你们的关系实际上是多对多的

车主可以拥有多辆车

我会将车辆和车主分开,并在另一个实体中管理他们的关系 换句话说,你需要三张桌子


不确定我是否更改了您的问题或提供了答案:)

我认为NHibernate不可能自动加载“Owner”属性。但是,您应该能够编写查询以获取车辆的当前所有者。看起来您已经有了一个带有
vehicleulservice
的车辆存储库/服务。我将添加一个类似于
GetCurrentOwner()
的方法,该方法接受一个参数,即车辆ID。然后让您的
Vehicle.Owner
属性通过传递自己的ID来调用此方法

基于条件的查询可能如下所示:

session.CreateCriteria(typeof(Owner))
    .CreateCriteria("OwnedVehicles") // Property path to the OwnerVehicle join table
        .Add(Expression.IsNull("EndDate"))
        .CreateCriteria("Vehicle")
            .Add(Expression.IdEq(id))
            .UniqueResult<Owner>();
session.CreateCriteria(类型(所有者))
.CreateCriteria(“OwnedVehicles”)//OwnerVehicle联接表的属性路径
.Add(Expression.IsNull(“EndDate”))
.1.1标准(“车辆”)
.Add(表达式.IdEq(id))
.UniqueResult();

我无法将车主ID存储在车辆表中,因为车主取决于日期。例如,我可以使:Vehicle Owner StartDate EndDate 1 1 04/04/2009 04/10/2009 1 2 05/10/2009为空。因此,我必须按EndDate进行筛选以使资产I已经有三个表:Vehicle、Owner和OwnerVehicle。问题是我必须在vehicle.cs中引用当前所有者。我不知道如何进行映射。我的类vehicle中已经有一个对owner的引用,所以vehicle.owner在我的代码中出现在各个方面。当我写入Vehicle v=VehicleService.Search(id)时;车辆如何加满?你的意思是:“车辆所有人如何加满”?NHibernate创建一个PersistentBag或其他东西,并将其分配给属性的(私有)setter。您无法访问属性setter中的列表,因为它可能尚未初始化。