【问题标题】:Fluent Nhibernate mapping multiple classes to single foreign keyFluent Nhibernate 将多个类映射到单个外键
【发布时间】:2010-11-17 01:26:49
【问题描述】:

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

例如:

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 的引用,它会起作用。如何在同一列(“ShirtId”)上有两个引用?或者,还有更好的方法?我无法真正更改表结构。

【问题讨论】:

    标签: .net nhibernate fluent-nhibernate


    【解决方案1】:

    这种关系如何运作? 通常,Person 佩戴ShirtShirt 要么是Shirt,要么是SpecialShirt。因为SpecialShirtShirt,所以Person 只需要引用Shirt。 NHibernate 知道所有关于每个具体类的 table-per-concrete-class 映射(这就是你所拥有的)。

    【讨论】:

    • 如果 Person 只引用了 Shirt,那么它将如何引用 SpecialShirt 的任何属性?创建对 SpecialShirt 的引用是否更有意义? (另外,为我令人费解的人/衬衫模型道歉。回想起来,我意识到我的创造性混淆尝试没有任何意义。)
    • 我认为您误解了如何进行继承。去阅读 Liskov-substitution principal。
    • 我不知道它叫那个,但我明白。我认为我的主要问题是解决试图合并继承的数据库结构。在数据库中,有一个 Person 表和两个向 Person 添加列的“扩展”表。同样,有一个 Shirt 表和两个向 Shirt 添加列的表。我有第三个类,它引用了已经假定非扩展/子类的 Person 和映射。无论如何,感谢您的帮助!
    【解决方案2】:

    我找到了解决方案。这很丑陋,但它正在工作。我将命令 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();
     }
    }
    

    然后我必须分别保存 Shirt 和 Person,因此级联无法真正工作。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-26
      • 2010-12-09
      • 1970-01-01
      • 2012-02-17
      • 2011-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多