Fluent Nhibernate将多个类映射到单个外键

时间:2010-11-10 21:29:07

标签: .net nhibernate fluent-nhibernate

我有一个数据库结构,其中一个表扩展另一个表,然后第三个表有一个在前两个表中有效的外键。

例如:

TABLE Person
PersonId int
Name varchar
ShirtId int

TABLE Shirt
ShirtId int
Color string

TABLE SpecialShirt
ShirtId int
Sleeves int

这些课程如下:

public class Person
{
    public virtual int PersonId { get; set; }
    public virtual string Name { get; set; }
    public virtual Shirt Shirt { get; set; }
    public virtual SpecialShirt SpecialShirt { get; set; }
}

public class Shirt
{
    public Shirt()
    {
        PersonList = new List<Person>();
    }

    public virtual int ShirtId { get; set; }
    public virtual string Color { get; set; }
    public virtual IList<Person> PersonList { get; set; }
    public virtual void AddPerson(Person p)
    {
        PersonList.Add(p);
    }
}

public class SpecialShirt : Shirt
{
    public virtual int Sleeves { get; set; }
}

映射看起来像这样:

public class TestPersonMap : ClassMap<TestPerson>
{
    public TestPersonMap()
    {
        Table("TestPerson");
        Id(x => x.PersonId).GeneratedBy.Native();
        Map(x => x.Name);
        References(x => x.Shirt).Column("ShirtId");
        References(x => x.SpecialShirt).Column("ShirtId"); // commenting out this line works
    }
}

public class TestShirtMap : ClassMap<TestShirt>
{
    public TestShirtMap()
    {
        Table("TestShirt");
        Id(x => x.ShirtId).GeneratedBy.Native();
        Map(x => x.Color);
        HasMany(x => x.PersonList).KeyColumn("ShirtId").Inverse().Cascade.All();
    }
}

public class TestSpecialShirtMap : SubclassMap<TestSpecialShirt>
{
    public TestSpecialShirtMap()
    {
        Table("TestSpecialShirt");
        KeyColumn("ShirtId");
        Map(x => x.Sleeves).Column("Sleeves");
    }
}

然后我尝试像这样保存一个新的Person和Shirt实例:

var shirt1 = new TestShirt() {Color = "Red"};
var person1 = new TestPerson() {Name = "Fred Person", Shirt = shirt1};
shirt1.AddPerson(person1);

session.Save(shirt1);
session.Save(person1);

此代码出现以下错误:

System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

如果我将Person中的引用移到SpecialShirt,它会起作用。 Howe我可以在同一列(“ShirtId”)上有两个引用吗?或者,还有更好的方法?我无法真正改变表结构。

2 个答案:

答案 0 :(得分:0)

这种关系如何运作? 通常,PersonShirt个,ShirtShirtSpecialShirt。由于SpecialShirtShirt,因此人只需要引用Shirt。 NHibernate知道所有关于table-per-concrete-class映射的知识(这就是你所拥有的)。

答案 1 :(得分:0)

我找到了解决方案。这很难看,但它有效。我将命令DynamicInsert()添加到PersonMap中。所以地图现在是:

public class TestPersonMap : ClassMap<TestPerson>
{
 public TestPersonMap()
 {
  Table("TestPerson");
  Id(x => x.PersonId).GeneratedBy.Native();
  Map(x => x.Name);
  References(x => x.Shirt).Column("ShirtId");
  References(x => x.SpecialShirt).Column("ShirtId"); 

  DynamicInsert();
 }
}

然后我必须单独保存衬衫和人员,所以级联不是真的有效。

到目前为止这是有效的。老实说,我不知道DynamicInsert做了什么。在研究这种方法时,我只能找到过时的文档和无用的论坛帖子。

我只能假设这将在未来的某个时候失败。