2010-03-25 44 views
1

如果這是一個天真的問題,首次使用NHibernate/Fluent搖擺它,所以提前道歉。我有一套我想要映射的模型。當我創建會話工廠時,我試圖一次完成所有映射。我沒有使用自動映射(儘管如果我正在嘗試做的事情最終會變得比它應該更痛苦)。我遇到的問題是,似乎只有頂級地圖正在採取。給定下面的代碼片段並運行一個試圖保存'bar'的單元測試,它會失敗並檢查我看到的日誌NHibernate試圖將一個bar實體保存到foo表中。雖然我懷疑這是我的映射,但它可能是我簡單忽略的其他東西。創建會話工廠如何使用FluentHibernate配置多個映射?

代碼(注意我也試過單獨調用到.Mappings):

Fluently.Configure().Database(MsSqlConfiguration.MsSql2008 
    .ConnectionString(c => c 
     .Server(@"localhost\SQLEXPRESS") 
     .Database("foo") 
     .Username("foo") 
     .Password("foo"))) 
    .Mappings(m => 
     { 
      m.FluentMappings.AddFromAssemblyOf<FooMap>() 
       .Conventions.Add(FluentNHibernate.Conventions.Helpers 
       .Table.Is(x => "foos")); 
      m.FluentMappings.AddFromAssemblyOf<BarMap>() 
       .Conventions.Add(FluentNHibernate.Conventions.Helpers 
       .Table.Is(x => "bars")); 
     }) 
    .BuildSessionFactory(); 

單元測試代碼片段:

using (var session = Data.SessionHelper.SessionFactory.OpenSession()) {  
    var bar = new Bar(); 
    session.Save(bar); 
    Assert.NotNull(bar.Id); 
} 

回答

2

你做錯了。 :)

首先,m.FluentMappings.AddFromAssemblyOf<FooMap>()m.FluentMappings.AddFromAssemblyOf<BarMap>()都在做同樣的事情(如果FooMapBarMap在同一個組件)。每一個只是告訴Fluent NHibernate掃描包含泛型類型的程序集;所以如果兩個類型都在同一個程序集中,它會掃描兩次。

其次,Conventions調用沒有作用於您所調用的特定程序集,而是針對整個映射集。所以你要做的是提供兩個約定來將表名設置爲明確的值,而第二個約定是最後一個應用。你想要做的是使用x參數(這是實體類型)並從中創建表名。

你需要的是這樣的:

.Mappings(m => 
{ 
    m.FluentMappings.AddFromAssemblyOf<FooMap>() 
    .Conventions.Add(Table.Is(x => x.Name + "s")); 
}) 

顯然,我的實現是天真的,並根據你的表命名約定,你可能想使用一個pluraliser(我相信城堡有一個,但它不應該很難找到一個與谷歌)。

您可以通過Fluent NHibernate wiki瞭解關於conventions的更多信息。

+0

我想盡可能多,謝謝,這有助於。 – 2010-03-25 18:07:05

0

與您指定表名類映射mapping。如果未指定,則它將與實體類名稱相同。

class FooMap : ClassMap<Foo> 
{ 
    public FooMap() 
    { 
     Table("foos"); 
    } 
} 

Conventions適用於所有映射。當您添加2個表名稱約定時,只有1個會生效。

您的FooMap和BarMap是否在同一個程序集中?你只需要添加一個程序集。

.Mappings(m => m.FluentMappings.AddFromAssemblyOf<FooMap>()) 
+0

這也有幫助!在兩個答案之間,我認爲我很好去。 – 2010-03-25 18:07:59

0

只是想分享這個會自動添加複數名稱或者s,es,ies基於結束字母表。不太確定語法和一些例外,但這對我來說似乎很好。任何異常使用Table("foos")就像@Lachlan羅氏所說。例如。 客戶類將有客戶表和類別類將有類別表。

修改@詹姆斯格雷戈裏答案:

.Mappings(m => 
{ 
    m.FluentMappings.AddFromAssemblyOf<FooMap>() 
    .Conventions.Add(Table.Is(x => GetPluralName(x.Name)); 
}) 


public static string GetPluralName(string oldName) 
{ 
    // This is the very simple. Just ignore exception like days, boys, photos and other specific nouns. 
    if (oldName.EndsWith("y")) 
     return oldName.Remove(oldName.Length - 1) + "ies"; 
    else if (oldName.EndsWith("s") || oldName.EndsWith("e") || oldName.EndsWith("h") || oldName.EndsWith("z") || oldName.EndsWith("o")) // Sibilant consonant or "o" 
     return oldName + "es"; 
    return oldName + "s"; 
}