nhibernate:选择父母和最新的孩子

时间:2012-06-28 09:21:02

标签: nhibernate parent-child queryover

我有以下实体

public class Vehicle
{
    public virtual string InternalNumber { get; set; }
    public virtual IList<VehicleDriverHistory> DriverHistory { get; set; }
}

public class VehicleDriverHistory : HistoryEntity
{
    public virtual Vehicle Vehicle { get; set; }
    public virtual DriverPerson Driver { get; set; }
    public virtual DateTime Date { get; set; }
}

现在我需要根据“日期”选择每辆车,如果有,还有最新的VehicleDriverHistory-Entry。 但是我有点挣扎,我在sql中做这个没有问题,但到目前为止在nhibernate中失败了。

到目前为止我所拥有的:

VehicleDriverHistory vdHistory = null;
VehicleDriverHistory vdHistory2 = null;
q.Left.JoinAlias(x => x.DriverHistory, () => vdHistory);
q.Left.JoinAlias(x => x.DriverHistory, () => vdHistory2).Where(x => vdHistory2.Date > vdHistory.Date);
q.Where(x => vdHistory2.Id == null);

这不起作用,只是我试图将sql查询(产生正确的数据)“转换”为nhibernate。

那么,我如何选择父母和最新的孩子(如果没有,则选择无父母)

由于

更新

在Firos的帮助下,我最终得到了以下内容:

VehicleDriverHistory historyAlias = null;
var maxDateQuery = QueryOver.Of<VehicleDriverHistory>()
                   .Where(h => h.Vehicle == historyAlias.Vehicle)
                   .Select(Projections.Max<VehicleDriverHistory>(h => h.Date));

var vehiclesWithEntry = DataSession.Current.QueryOver(() => historyAlias)
                        .WithSubquery.WhereProperty(h => h.Date).Eq(maxDateQuery)
                        .Fetch(h => h.Vehicle).Eager
                        .Future();

Vehicle VehicleAlias = null;
var vehiclesWithoutEntry = DataSession.Current.QueryOver<Vehicle>(() => VehicleAlias)
                           .WithSubquery
                           .WhereNotExists(QueryOver.Of<VehicleDriverHistory>()
                           .Where(x => x.Vehicle.Id == VehicleAlias.Id).Select(x => x.Id))
                           .Future();

return vehiclesWithEntry.Select(h => new PairDTO { Vehicle = h.Vehicle, NewestHistoryEntry = h }).Concat(vehiclesWithoutEntry.Select(v => new PairDTO { Vehicle = v })).ToList();

我不得不用vehquery子句替换vehclesWithoutEntry中的Any()语句,因为它引发了异常。

1 个答案:

答案 0 :(得分:1)

使用期货只进行一次往返的其他想法

VehicleDriverHistory historyAlias = null;
var maxDateQuery = QueryOver.Of<VehicleDriverHistory>()
    .Where(h => h.Vehicle == historyAlias.Vehicle)
    .Select(Projections.Max<VehicleDriverHistory>(h => h.Date));

var vehiclesWithEntry = session.QueryOver(() => historyAlias)
    .WithSubquery.WhereProperty(h => h.Date).Eq(maxDateQuery)
    .Fetch(h => h.Vehicle).Eager
    .Select(h => new PairDTO { Vehicle = h.Vehicle, NewestHistoryEntry = h })
    .Future<PairDTO>();

var vehiclesWithoutEntry = session.QueryOver<Vehicle>()
    .Where(v => !v.DriverHistory.Any())
    .Select(v => new PairDTO{ Vehicle = v })
    .Future<PairDTO>();

return vehiclesWithoutEntry.Concat(vehiclesWithEntry); // .ToList() if immediate executing is required

更新:我无法重现异常,但你可以试试这个

VehicleDriverHistory historyAlias = null;
var maxDateQuery = QueryOver.Of<VehicleDriverHistory>()
    .Where(h => h.Vehicle == historyAlias.Vehicle)
    .Select(Projections.Max<VehicleDriverHistory>(h => h.Date));

var vehiclesWithEntry = session.QueryOver(() => historyAlias)
    .WithSubquery.WhereProperty(h => h.Date).Eq(maxDateQuery)
    .Fetch(h => h.Vehicle).Eager
    .Future();

var vehiclesWithoutEntry = session.QueryOver<Vehicle>()
    .Where(v => !v.DriverHistory.Any())
    .Select(v => new PairDTO{ Vehicle = v })
    .Future<PairDTO>();

return vehiclesWithoutEntry.Select(h => new PairDTO { Vehicle = h.Vehicle, NewestHistoryEntry = h }).Concat(vehiclesWithEntry);