c# - NHibernate 在具有复合键的遗留数据库中一对一

标签 c# nhibernate nhibernate-mapping legacy-database

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

用户

  • PK - 用户 ID
  • PK - GroupId
  • 位置来源
  • 等...

地点

  • PK - 用户 ID
  • PK - GroupId
  • PK - 来源
  • X

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

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

这些类看起来像这样:

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

我不知道如何将数据库方案映射到那些类。 到目前为止,我尝试的一切都失败了。

我会感谢你的帮助。

最佳答案

这是我的做法。

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

默认情况下,User.Locations 和 User.Source 都会延迟加载,但您可以使用任何查询选项来预先加载 User.Source 以获取当前位置以获取您的利益。

当您通过 Locations 属性向用户添加 Location 时,您显然还需要管理 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();
    }
}

关于c# - NHibernate 在具有复合键的遗留数据库中一对一,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6001814/

相关文章:

sqlite - 通过NHibernate创建SQLite触发器

nhibernate - 使用 NHibernate 的 CreateCriteria 方法时如何强类型化条件?

c# - 删除抛出 "deleted object would be re-saved by cascade"

nhibernate映射: A collection with cascade ="all-delete-orphan" was no longer referenced

c# - 使用 NHibernate 映射一对多的最小且正确的方法

c# - .NET 4.5 中的 HttpListener 无法将套接字识别为 WebSocket

C# 垃圾回收

c# - Treeview ContainerFromItem 总是返回 null

如果集合中的子项具有特定值,则用于选择父项的 nHibernate 标准

c# - 如何从数据库创建html格式的子菜单?