NHibernate один-к-одному в устаревшей базе данных с составным ключом - PullRequest
3 голосов
/ 14 мая 2011

У нас есть устаревшая база данных, с которой мы хотим считывать данные с помощью NHibernate.Таблицы, которые мы хотим отобразить, следующие:

Пользователи

  • PK - UserId
  • PK - GroupId
  • LocationSource
  • и т.д ...

Местоположение

  • PK - идентификатор пользователя
  • PK - идентификатор группы
  • PK - источник
  • X
  • Y

У каждого пользователя есть одно или несколько местоположений.Местоположение может быть введено из разных источников, которые обозначены столбцом Source.столбец L ocationSource таблицы Users содержит наиболее релевантный источник местоположения для этого пользователя.

В текущем приложении, которое мы пишем, нам нужно только последнее местоположение.это делается главным образом из соображений производительности, мы не хотим загружать все местоположения (используя внешнее соединение) всякий раз, когда загружаем пользователя (о ленивой загрузке также не может быть и речи).

Классы будут выглядеть как-товот так:

public class UserKey
{
    public int UserId {get;set;}
    public int GroupId {get;set;
}

public class Location
{
    public double X {get;set;}
    public double Y {get;set;}
    public LocationSource Source {get;set;}
}

public class User
{
    public UserKey Id {get; set;}
    public Location Location {get;set;}
}

Я не могу понять, как сопоставить схему базы данных с этим классом.Все, что я пытался до сих пор не получилось.

Буду признателен за вашу помощь.

1 Ответ

0 голосов
/ 23 мая 2011

Вот как я бы это сделал.

Пользователь будет содержать как список (местоположения), так и ссылку на текущее местоположение (источник), поэтому вы получите текущее местоположение для каждого пользователя и исторический список пользователя.местоположения.

User.Locations и User.Source будут загружаться по умолчанию с отложенной загрузкой, но вы можете использовать любой из вариантов запроса, чтобы быстро загрузить User.Source, чтобы получить текущее местоположение для вашей выгоды.

Когдавы добавляете местоположение для пользователя через свойство Locations, которое вам, очевидно, понадобится для управления ссылкой на источник.

Если вам нужны файлы сопоставления XML, которые я могу предоставить, а также использовал Fluent NHibernate 1.1.

public class User
{
    public virtual int UserId { get; set; }
    public virtual int GroupId { get; set; }
    public virtual IList<Location> Locations { get; set; }
    public virtual Location Source { get; set; }
    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;
        var t = obj as User;
        if (t == null)
            return false;
        if (UserId == t.UserId && GroupId == t.GroupId)
            return true;
        return false;
    }
    public override int GetHashCode()
    {
        return (UserId + "|" + GroupId).GetHashCode();
    }
}

public class Source
{
    public virtual int Id { get; set; }
}

public class Location
{
    public virtual User User { get; set; }
    public virtual int Id { get; set; }
    public virtual Source Source { get; set; } 
    public virtual string X { get; set; }
    public virtual string Y { get; set; }
    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;
        var t = obj as Location;
        if (t == null)
            return false;
        if (User == t.User && Source == t.Source)
            return true;
        return false;
    }
    public override int GetHashCode()
    {
        return (User.GetHashCode() + "|" + Id).GetHashCode();
    }
}

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        CompositeId()
            .KeyProperty(x => x.UserId, "UserId")
            .KeyProperty(x => x.GroupId, "GroupId");
        HasMany(x => x.Locations);
        References(x => x.Source).Columns("UserId", "GroupId", "LocationSource");
    }
}

public class LocationMap : ClassMap<Location>
{
    public LocationMap()
    {
        CompositeId()
            .KeyReference(x => x.Source, "Source")
            .KeyReference(x => x.User,"groupId","userid");
        References(x => x.User).Columns("userid","groupid");
    }
}

public class SourceMap : ClassMap<Source>
{
    public SourceMap()
    {
        Id(x => x.Id).GeneratedBy.Native();
    }
}
...