儿童集合和一对一

时间:2014-01-15 17:51:17

标签: linq nhibernate fluent-nhibernate linq-to-nhibernate nhibernate-criteria

我的实体“TimeRecord”包含“WayPoint s”和两个一对一属性“Location”和“WayData”的集合。

每个属性都可以为null。

我需要使用特定用户的初始化属性导出所有时间记录。

我实际上有一个有效的解决方案,但之后我开始使用NHibernateProiler,首先我注意到这段代码会导致对db的查询数量过多。

var query = (from timeRecord in Session.Query<TimeRecord>()
                .Where(tr => tr.User.Id == userid)
            select timeRecord);

然后我将代码更改为:

var query = (from post in Session.Query<TimeRecord>()
                .Fetch(x => x.Location)
                .Fetch(x => x.WayData)
                .FetchMany(x => x.WayPoints)
                .Where(tr => tr.User.Id == userid)
            select post);

这导致我遇到笛卡尔积问题。

现在我正在尝试这段代码:

 var sql1 = "from TimeRecord b left outer join fetch b.Location where b.User.Id=:User_id";
 var sql2 = "from TimeRecord b left outer join fetch b.WayData where b.User.Id=:User_id";
 var sql3 = "from TimeRecord b left inner join fetch b.WayPoints where b.User.Id=:User_id";


var result = Session.CreateMultiQuery()
             .Add(Session.CreateQuery(sql1))
             .Add(Session.CreateQuery(sql2))
             .Add(Session.CreateQuery(sql3))
             .SetParameter("User_id", userid)
             .List();

但我不能说这是否是正确的方法,或者如果nHibernate甚至可以做到这一点。有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

1 + N 问题通常是实体/集合映射和ORM工具。但NHibernate有一个非常好的解决方案,如何正确管理它。它被称为:

此设置允许:

  • 继续查询根实体(在我们的案例中为TimeRecord
  • 查询内部没有提取(Session.Query<TimeRecord>())。这意味着我们确实支持正确的分页。 Take()Skip()将在展示根表格上执行
  • 所有集合都将加载自己的SELECT语句(看起来可能是劣势,但在下面)
  • 更多更少 SELECT然后1 + N.所有这些都将被批量处理。例如。由25条记录
  • 所有原生地图(集合的延迟加载)仍然存在......

xml映射示例:

-- class level
<class name="Location" batch-size="25 ...

-- collection level
<batch name="Locations" batch-size="25" ...

我建议将其应用于所有馆藏/班级。 使用Fluent映射,也可以使用约定来完成

流畅的映射:

// class
public LocationMap()
{
    Id(x => x....
    ...
    BatchSize(25);

// collection
HasMany(x => x.Locations)
  ...
  .BatchSize(25);