nHibernate 一对一属性 null 加载时



我在时间记录和位置之间有一个一对一的关系。此实现与文档中描述的 es 完全相同:https://github.com/jagregory/fluent-nhibernate/wiki/Fluent-mapping

 public class TimeRecordMap : ClassMap<TimeRecord>
{
    public TimeRecordMap()
    {
        Id(x => x.Id);
        Map(x => x.Description);
        Map(x => x.StartTime);
        Map(x => x.EndTime);

        HasOne(x => x.Location).Cascade.All();
    }
}
   public class LocationMap : ClassMap<Location>
{
    public LocationMap()
    {
        Id(x => x.Id);
        Map(x => x.Longitude);
        Map(x => x.Latitude);
        Map(x => x.Adress);
        References(x => x.TimeRecord).Unique();

    }
}

现在我使用以下方法查询我的时间记录:

  public IList<TimeRecord> GetTimeRecords(string userid)
    {
        var query = Session.Query<TimeRecord>().Where(tr => tr.User.Id == userid);
        return query.ToList();
    }

不幸的是,即使位置表中有一个共同的条目,我的位置对象也总是为空,但是当我查询具有所需TimeRecordId的应答位置时,它会正确返回。

请参阅此处的代码(代码位于循环内 ->trCurrent 是从"GetTimeRecords "接收的列表中的当前对象)

  Location location = _locationRepo.getLocationByTimeRecordId(trCurrent.Id);
                //trCurrent.Location = location; <- don't want to do it that way
                if (trCurrent.Location != null)<- always null
                {
                       ... do stuff here
                }

实现我的位置存储库方法:

  public Location getLocationByTimeRecordId(int timeId)
    {
        var query = Session.Query<Location>()
                    .Where(tr => tr.TimeRecord.Id == timeId && tr.IsDeleted == false);
        List<Location> lstReturn = query.ToList();
        if (lstReturn.Count() == 0)
        {
            return null;
        }
        else
        {
            return lstReturn.First();
        }
    }

有人可以告诉我为什么我的位置没有正确解决吗?

干杯斯特凡

人们声称

HasOne/一对一通常保留用于特殊情况。通常,在大多数情况下,您会使用引用/多对一关系(请参阅:我认为您的意思是多对一)。如果你真的想要一对一,那么你可以使用HasOne方法。

如果您确实想要一对一并使用它,则应记住,默认情况下,实体由其 ID 连接。

如果您检查生成的 SQL,您将看到类似 JOIN Location ON Location.Id = TimeRecord.Id 的内容。

为了获得像JOIN Location ON Location.TimeRecordId = TimeRecord.Id这样的SQL,您应该通过PropertyRef()方法指定外键。所以你的映射可能是下面的:

public class TimeRecordMap : ClassMap<TimeRecord>
{
    public TimeRecordMap()
    {
        Id(x => x.Id);
        Map(x => x.Description);
        Map(x => x.StartTime);
        Map(x => x.EndTime);
        HasOne(x => x.Location).Cascade.All().PropertyRef(it => it.TimeRecord);
    }
}
public class LocationMap : ClassMap<Location>
{
    public LocationMap()
    {
        Id(x => x.Id);
        Map(x => x.Longitude);
        Map(x => x.Latitude);
        Map(x => x.Adress);
        References(x => x.TimeRecord/*, "TimeRecordId"*/).Unique().Not.Nullable();        
    }
}

为了确保任何位置都有TimeRecord您可以将.Not.Nullable()添加到LocationMap类中。

最新更新