我有一对多的关系,但我想只有一个实例有一对一的关系。
我有一类车辆,可能会有几个车主一生。我只想映射该类以获取资产。有没有办法做到这一点?
问题出在hbm.xml文件中。一辆车一生可能有几个车主,但我想只获得最后一个车主。我需要通过vehiculeId,ownerId和EndDate进行过滤。我想用资产填充在vehicle.cs中的对象所有者。
当我写:Vehicule v = VehiculeService.SearchVehicule(id);
我希望v.Owner必须包含最后一辆车的所有者。
我无法将所有者的ID存储在车辆牌桌上,因为所有者依赖于日期。我可以举例如: 车主StartDate EndDate 1 1 04/04/2009 04/10/2009 1 2 05/10/2009 NULL
出于这个原因,我必须通过EndDate过滤才能拥有资产
我有三个表:Vehicle,Owner和OwnerVehicle。问题是我必须在vehicle.cs中引用当前所有者。而且我不知道如何进行映射。
任何帮助将不胜感激。感谢
答案 0 :(得分:0)
一种简单的映射方法是将其转换为多对一关系,并将当前所有者的ID存储在车辆表中。我知道这可能是架构更改。
一种欺骗这种方法的方法是创建一个基本上是车辆表的视图加上它将拉动当前的所有者。这样您就不必更改架构,然后映射到视图而不是表。
我不确定在这种情况下定义你自己的加载器是否会起作用,但它还有一个可以探索的选择。
我了解你的预测。最简单的方法是修改架构和应用程序以添加这个额外的列,以假冒它将与视图。例如,
select vehicle.*, owner.ownerid
from vehicle
inner join owner
on owner.vehicleid=vehicle.vehicle
and owner.enddate is null
我假设当前所有者的结束日期为空。现在,您将映射更改为映射到视图而不是表。是的,这是一个黑客,但它会工作。
我假设你仍然需要在nHibernate中映射所有者?另一种选择是在Owner's类映射上添加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);
}
}
}
答案 1 :(得分:0)
您可以使用Criteria(或DetachedCriteria for Spring)对象在执行搜索时限制其他值。
答案 2 :(得分:0)
我建议在业务层中维护此引用,并将其映射为多对一关系。我的意思是您在代码中明确设置此引用。这使您也可以直接找到当前所有者的车辆。
示例:
<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;
}
答案 3 :(得分:0)
您的关系实际上是多对多的
拥有者可拥有多辆车
我会让车辆和车主分开并管理他们在另一个实体的关系 换句话说 - 你需要三张桌子
不确定我是否更改了您的问题或提供了答案:)
答案 4 :(得分:0)
我认为NHibernate不能自动加载“Owner”属性。但是,您应该能够编写查询以获取车辆的当前所有者。看起来您已经拥有VehiculeService
的Vehicle存储库/服务。我会添加一个像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>();