문제

I have a One to One relation between a TimeRecord and the Location. This implementation is exactly the same es described in documentation: 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();


    }
}

Now I query my TimeRecords with the following method:

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

Unfortunalelty my Location object is always null even if there is a coresponding entry in Location table but when I query for the coresponding Location with the desired TimeRecordId it is returned correctly.

See code here (code is inside a loop -> trCurrent is the current object in list received from "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
                }

Implementation of my LocationRepository method:

  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();
        }
    }

Can someone tell me why my Location is not resolved corretly?

Cheers, Stefan

도움이 되었습니까?

해결책

People claim that

HasOne / one-to-one is usually reserved for a special case. Generally, you'd use a References / many-to-one relationship in most situations (see: I think you mean a many-to-one). If you really do want a one-to-one, then you can use the HasOne method.

If you really do want a one-to-one and use it, you should remember that entities are joined by their ids by default.

If you check generated SQL you'll see something like JOIN Location ON Location.Id = TimeRecord.Id.

In order to get SQL like JOIN Location ON Location.TimeRecordId = TimeRecord.Id you should specify the foreign key via PropertyRef() method. So your mapping could be the folloving:

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();        
    }
}

In order to make sure that any location has TimeRecord you can add .Not.Nullable() into your LocationMap class.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top