NHibernate 在遗留数据库中使用复合键一对一

发布于 2024-11-07 01:42:23 字数 912 浏览 0 评论 0原文

我们有一个旧数据库,我们希望使用 NHibernate 从中读取数据。 我们要映射的表如下:

Users

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

Locations

  • PK - UserId
  • PK - GroupId
  • PK - Source
  • X
  • Y

每个用户都有一个或多个位置。可以从不同来源输入位置,这些来源由来源 列标识。 Users 表的 LlocationSource 列保存与该用户最相关的位置源。

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

这些类看起来像这样:

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

我无法弄清楚如何将数据库方案映射到这些类。 到目前为止我尝试的一切都失败了。

我会感谢你的帮助。

We have a legacy Database that we want to read data from using NHibernate.
The tables that we want to map are the following:

Users

  • PK - UserId
  • PK - GroupId
  • LocationSource
  • etc...

Locations

  • PK - UserId
  • PK - GroupId
  • PK - Source
  • X
  • Y

Every user has one or more locations. A location can be entered from different sources, which are identified by the Source column.
the Users table's LocationSource column holds the most relevant location source for that user.

In the current application we're writing, we need only the last location.
this is done mainly for performance reasons, we don't want to load all the locations (using outer join)
whenever we load a User (Lazy Loading is out of the question either).

The classes will look something like that:

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

I cannot figure out how to map the database scheme to those class.
Everything I tried failed so far.

I will appreciate your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

£冰雨忧蓝° 2024-11-14 01:42:23

我就是这样做的。

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

默认情况下,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();
    }
}

Here's how I would do it.

User would contain both a List (Locations) and a reference to the current Location (Source) therefore you get the current Location per User and the historic list of a User's Location's.

User.Locations and User.Source will both lazy load by default but you can use any of the query options to eager load User.Source to get the current location for your benefit.

When you add a Location to a User via the Locations property you will obviously need to manage the Source reference as well.

If you would like the XML mapping files I can provide as well as I have used 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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文