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