2010-11-10 91 views
1

我有一個數據庫結構,其中一個表擴展另一個表,然後第三個表具有在前兩個表中有效的外鍵。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"); 
    } 
} 

我再嘗試保存人的新實例和襯衫是這樣的:

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 

它的工作原理,如果我刪除從人到SpecialShirt參考。 Howe可以在同一列上添加兩個引用(「ShirtId」)嗎?或者,還有更好的方法?我無法真正改變表格結構。

回答

0

我找到了解決方案。這是醜陋的,但它的工作。我在PersonMap中添加了命令DynamicInsert()。所以地圖現在是:

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是幹什麼的。研究此方法時,我只能找到過時的文檔和無益的論壇主題。

我只能假設這將在未來某個時候失敗。

0

這種關係是如何工作的? 通常,Person穿戴Shirt,並且ShirtShirtSpecialShirt。因爲SpecialShirtShirt,所以Person只需要引用Shirt。 NHibernate知道所有關於table-per-concrete-class映射(這就是你所擁有的)。

+0

如果Person只有襯衫的引用,那麼它將如何引用SpecialShirt的任何屬性?創建對SpecialShirt的引用會更有意義嗎? (另外,對於我複雜的人物/襯衫模型表示歉意,我回想起來,我對創造性混淆的嘗試沒有任何意義。) – 2010-11-12 17:49:37

+0

我認爲你很想知道如何做繼承。去閱讀Liskov替代校長。 – 2010-11-15 17:21:57

+0

我不知道它被稱爲,但我明白這一點。我認爲我的主要問題是圍繞一個嘗試合併繼承的數據庫結構。在數據庫中,有一個Person表和兩個向「Person」添加列的「擴展」表。同樣,還有一張襯衫桌子和兩張向襯衫添加列的桌子。我有第三個類引用Person和已經承擔非擴展/子類的映射。無論如何,感謝您的幫助! – 2010-11-15 20:48:53

相關問題