2010-12-08 106 views
2

我發現下面的文章http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx幫助我測試我的NHibernate應用程序。我的大部分測試都能正常工作,但卻出現了一個奇怪的錯誤。通過觀察生成的SQL我相信下面流利的映射引起的問題:將NHibernate中的公式映射到SQLite或覆蓋映射中的函數

Map(x => x.IsValid).Formula("CASE WHEN dbo.NumPosts(UserID) = 5 THEN 1 ELSE 0 END"); 

你會注意到調用dbo.NumPosts這是我的數據庫中的用戶定義的函數。我知道還有其他的方法可以映射這個屬性,但這只是一個例子。基本上我需要知道如何使用SQLite進行映射。

編輯:

經過進一步的思緒會,是否有可能重寫我的單元測試的項目爲這一領域的映射?這是我目前的配置:

private static ISessionFactory CreateSessionFactory() { 
    return Fluently.Configure() 
     .Database(SQLiteConfiguration.Standard.InMemory().ShowSql()) 
     .Mappings(m => m.FluentMappings 
      .AddFromAssembly(typeof(Role).Assembly) 
      .Conventions.AddFromAssemblyOf<EnumConvention>()) 
     .ExposeConfiguration(c => _configuration = c) 
     .BuildSessionFactory(); 
} 

我不希望重新定義所有的映射,因爲這需要一些時間,並將變得不可維護。

我會很感激的幫助。謝謝

回答

0

問題解決!我能說:

[SQLiteFunction(Name = "NumPosts", Arguments = 1, FuncType = FunctionType.Scalar)] 
public class NumPosts : SQLiteFunction { 
    public override object Invoke(object[] args) { 
     ... 
    } 
} 

現在我要做的就是添加一個設置加在我的職務DBO前綴盈。然後在測試項目中將其設置爲空白。

+0

你在哪裏發現你正在使用哪種nhibernate方言來處理包括'dbo'。或不? – NYCChris 2012-02-26 16:41:37

1

參考你評論中的答案,我能夠得到一個靜態布爾屬性的工作。

不過我不喜歡依賴全局布爾變量,所以我決定進一步挖掘。在NHibernate 3.0中,他們將事件添加到配置對象中。特別是我能夠利用Configuration對象上的新的BeforeBind事件。

我重寫了一下你的CreateSessionFactory()方法來展示我是如何做到的。

注意:在我的公式中,我總是將它們編寫爲dbo.NumPosts,並且事件處理程序將刪除'dbo'。如果我們在SQLite方言中運行。

private static ISessionFactory CreateSessionFactory() 
{ 
    return Fluently.Configure() 
     .Database(SQLiteConfiguration.Standard.InMemory().ShowSql()) 
     .Mappings(m => m.FluentMappings 
          .AddFromAssembly(typeof (Role).Assembly) 
          .Conventions.AddFromAssemblyOf<EnumConvention>()) 
     .ExposeConfiguration(c => 
           { 
            c.BeforeBindMapping += BeforeBindMappingHandler; 
            _configuration = c; 
           }) 
     .BuildConfiguration() 
     .BuildSessionFactory(); 
} 

private static void BeforeBindMappingHandler(object sender, BindMappingEventArgs e) 
{ 
    if (!(e.Dialect is SQLiteDialect)) return; 

    var properties = e.Mapping.RootClasses 
     .SelectMany(r => r.Properties) 
     .Where(p => p is HbmProperty) 
     .Cast<HbmProperty>() 
     .Where(p => p.Formulas.Any()); 

    foreach (var hbmProperty in properties) 
     hbmProperty.formula = hbmProperty.formula.ToLower().Replace("dbo.", ""); 
}