11

我們在公司工作時使用Fluent NHibernate作爲數據對象模型。 幾天前,我們遇到了一個問題,即Fluent NHibernate會生成一個額外的列,這個列在模型和映射中都不存在。這裏的情況是:流利的NHibernate生成額外的列

我的模型:FirstClass.cs

public class FirstClass 
{ 
    public virtual int Id { get; private set; } 
    public virtual SecondClass MyReference { get; set; } 
    public virtual DateTime DecisionDate { get; set; } 
} 

我的映射:

public class FirstClassMap : ClassMap<FirstClass> 
{ 
    public FirstClassMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.DecisionDate); 

     References(x => x.MyReference); 
    } 
} 

用下面的代碼建立架構之後,

Instance._sessionFactory = Fluently.Configure() 
       .Database(MySQLConfiguration.Standard 
        .ConnectionString(connectionString) 
        .ShowSql()) 
       .ExposeConfiguration(c => 
       { 
        c.Properties.Add("current_session_context_class", ConfigurationHelper.getSetting("SessionContext")); 
       }) 
       .ExposeConfiguration(BuildSchema) 
       .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Community>()) 
       .BuildSessionFactory(); 

額外名爲「SecondClass_id」的列是使用Id列的SecondClass表的索引和外鍵生成的。這裏是產生的表:

CREATE TABLE `FirstClass` (
    `Id` int(11) NOT NULL AUTO_INCREMENT, 
    `DecisionDate` datetime DEFAULT NULL, 
    `MyReference_id` int(11) DEFAULT NULL, 
    `SecondClass_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`Id`), 
    KEY `MyReference_id` (`MyReference_id`), 
    KEY `SecondClass_id` (`SecondClass_id`), 
    CONSTRAINT `FK4AFFB59B2540756F` FOREIGN KEY (`MyReference_id`) REFERENCES `SecondClass` (`Id`), 
    CONSTRAINT `FK4AFFB59B51EFB484` FOREIGN KEY (`SecondClass_id`) REFERENCES `SecondClass` (`Id`), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

我發現,如果我重新命名「MyReference」到「二等」(同名的類類型),沒有創建額外的列。但我想用我指定的名稱來使用我的屬性,而不是用類名。爲什麼會創建額外的列?我如何解決這個問題?我不希望額外的外鍵列在附近。

+1

你的意思是如果你改變屬性名稱不同於對象名稱,它會創建兩個字段,一個是your_choosen_name other是object_name? – gandil 2011-05-19 12:21:57

+0

當然。任何想法爲什麼? – SadullahCeran 2011-05-19 12:23:12

+0

聽起來很奇怪。如果您明確指定列名,會發生什麼情況。參考文獻(x => x.MyReference,「SecondClass_id」); – 2011-05-19 12:46:45

回答

18

當您使用FNH並且您在實體之間存在雙向關係時,通常會發生這種情況。

public class FirstClass 
{ 
    public virtual SecondClass MyReference { get; set; } 
} 

public class SecondClass 
{ 
    public virtual List<FirstClass> ListOfFirstClass { get; set; } 
} 

public class FirstClassMap : ClassMap<FirstClass> 
{ 
    public FirstClassMap() 
    { 
     References(x => x.MyReference); 
    } 
} 

public class SecondClassMap : ClassMap<SecondClass> 
{ 
    public SecondClassMap() 
    { 
     HasMany(x => x.ListOfFirstClass); 
    } 
} 

爲了解決這個問題,你必須覆蓋在任何類映射使用的列名,例如:

public class SecondClassMap : ClassMap<SecondClass> 
{ 
    public SecondClasssMap() 
    { 
     HasMany(x => x.ListOfFirstClass).KeyColumn("MyReference_id"); 
    } 
} 

或:

public class FirstClassMap : ClassMap<FirstClass> 
{ 
    public FirstClassMap() 
    { 
     References(x => x.MyReference).Column("SecondClass_id"); 
    } 
} 

這樣做的原因是,FNH對待每映射爲單獨的關係,因此創建不同的列,鍵和索引。

+0

感謝您的好評,我會試一試。 – SadullahCeran 2011-06-14 09:45:21

+0

'HasMany()'沒有'Column()'方法,而是使用'KeyColumn()'。 – 2011-09-14 15:35:55

+0

@Gweebz謝謝你提供我的錯字,我已經更新了我的答案。 – 2011-09-15 14:31:57