NHibernate在具有复合密钥的旧数据库中一对一

时间:2011-05-14 12:27:51

标签: c# nhibernate nhibernate-mapping legacy-database

我们有一个遗留数据库,我们想要使用NHibernate读取数据。 我们要映射的表格如下:

用户

  • PK - UserId
  • PK - GroupId
  • LocationSource
  • 等...

位置

  • PK - UserId
  • PK - GroupId
  • PK - 来源
  • X
  • ý

每个用户都有一个或多个位置。可以从不同来源输入位置,这些来源由Source列标识。 Users表的L ocationSource列包含该用户最相关的位置源。

在我们正在编写的当前应用程序中,我们只需要最后一个位置。 这主要是出于性能原因,我们不想加载所有位置(使用外连接) 每当我们加载用户时(懒惰加载都是不可能的)。

这些类看起来像这样:

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 :(得分:0)

我将如何做到这一点。

用户将包含列表(位置)和对当前位置(源)的引用,因此您将获得每个用户的当前位置和用户位置的历史列表。

默认情况下,User.Locations和User.Source都将延迟加载,但您可以使用任何查询选项来急切加载User.Source以获取当前位置以供您使用。

当您通过Locations属性向用户添加位置时,您显然也需要管理Source引用。

如果你想要我提供的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();
    }
}