NHibernate将1个对象映射到2个表

时间:2011-09-06 03:48:58

标签: c# .net nhibernate orm fluent-nhibernate

我们希望在我们的应用程序中使用NHibernate作为持久层。我们也使用Fluent NHibernate进行映射。

我们从第三方获取Person数据,我们需要将数据保存到我们的数据库中。它在代码中更好地在一个对象上具有所有属性,但将数据保存到数据库中的两个表更有意义。

我们的对象如下:

public class Person
{
    public virtual long VersionNumber { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string IdentificationNumber { get; set; }
}

我们的数据库表如下所示:

CREATE TABLE PersonVersion (
    [PK] VersionNumber bigint NOT NULL,
    [FK] PersonDemographicsId int NOT NULL
)
CREATE TABLE PersonDemographics (
    [PK] PersonDemographicsId int NOT NULL,
    IdentificationNumber nvarchar(9) NOT NULL,
    FirstName nvarchar(100) NOT NULL,
    LastName nvarchar(100) NOT NULL
)

当我们收到新数据时,版本号可能会发生变化,但其他人口统计数据可能会相同。我们需要NHibernate做的是将新记录保存到链接到现有PersonVersion记录的PersonDemographics表。如果人口统计信息已更改,那么我们将在两个表中创建新记录。但大多数情况下,一旦我们下载了初始数据,人口统计数据就不会像版本号那样频繁变化。我们需要跟踪所有版本号,这就是为什么需要创建新的PersonVersion记录。

我们如何使用NHibernate和使用Fluent NHibernate进行映射来实现这一目标?

另外,正如您所看到的,我们的Person对象目前没有PersonDemographicsId,因为我们的应用程序根本不需要它;它只是数据库中所需的表关系的ID。为了在NHibernate中正确映射它,我们是否必须在Person对象上添加PersonDemographicsId属性?

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

本文http://ayende.com/blog/2327/multi-table-entities-in-nhibernate解释了将单个类映射到数据库中的两个表的方法。

答案 1 :(得分:0)

只是一个想法,也许必须调整

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

    internal protected virtual IList<long> VersionNumbers { get; set; }
    public virtual long VersionNumber {
       get { return VersionNumbers[VersionNumbers.Count - 1]; }
       set { VersionNumbers.Add(value); }
    }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual string IdentificationNumber { get; set; }
}

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        Table("PersonDemographics");
        Id(p => p.Id, "PersonDemographicsId").GeneratedBy.Assigned();
        Map(p => p.FirstName);
        Map(p => p.LastName);
        Map(p => p.IdentificationNumber);

        HasMany(p => p.VersionRecord)
            .Table("PersonVersion")
            .KeyColumn("PersonDemographicsId")
            .Element("VersionNumber")
            .OrderBy("VersionNumber")
            .Cascade.All();
    }
}