NHibernate中的公式映射到SQLite或覆盖映射中的函数

时间:2010-12-08 16:16:34

标签: nhibernate sqlite fluent-nhibernate

我找到了以下文章http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx来帮助我对我的NHibernate应用程序进行单元测试。我的大多数测试工作正常,但抛出了一个奇怪的错误。从查看生成的SQL我相信以下流畅的映射导致了问题:

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();
}

我不希望重新定义所有映射,因为这需要一些时间并且会变得无法维护。

我很感激帮助。感谢

2 个答案:

答案 0 :(得分:1)

参考评论中的答案,我能够获得静态bool属性。

我仍然不喜欢依赖全球bool变量,所以我决定进一步挖掘。在NHibernate 3.0中,他们向Configuration对象添加了事件。特别是我能够利用Configuration对象上的新BeforeBind事件。

我稍微重写了你的CreateSessionFactory()方法,以显示我是如何做到的。

注意:在我的公式中,我总是把它们写成dbo.NumPosts,事件处理程序将删除'dbo'。如果我们在SQLite Dialect中运行。

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.", "");
}

答案 1 :(得分:0)

问题解决了!我能够说:

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

现在我所要做的就是添加一个设置来添加我的函数前面的dbo前缀。然后在测试项目中将其设置为空白。

相关问题