NHibernate中的公式映射到SQLite中的函数或重写映射

NHibernate中的公式映射到SQLite中的函数或重写映射,nhibernate,sqlite,fluent-nhibernate,Nhibernate,Sqlite,Fluent Nhibernate,我发现下面的文章可以帮助我对我的NHibernate应用程序进行单元测试。我的大多数测试都运行良好,但出现了一个奇怪的错误。从生成的SQL来看,我认为以下fluent映射导致了这些问题: Map(x => x.IsValid).Formula("CASE WHEN dbo.NumPosts(UserID) = 5 THEN 1 ELSE 0 END"); 您将注意到对dbo.NumPosts的调用,它是我的数据库中的一个用户定义函数。我知道还有其他方法可以映射这个属性,但这只是一个例子。

我发现下面的文章可以帮助我对我的NHibernate应用程序进行单元测试。我的大多数测试都运行良好,但出现了一个奇怪的错误。从生成的SQL来看,我认为以下fluent映射导致了这些问题:

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();
}
私有静态ISessionFactory CreateSessionFactory(){
流畅地返回。Configure()
.Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
.Mappings(m=>m.FluentMappings
.AddFromAssembly(类型(角色).Assembly)
.Conventions.AddFromAssemblyOf())
.ExposeConfiguration(c=>_configuration=c)
.BuildSessionFactory();
}
我不希望重新定义所有映射,因为这需要一些时间,并且将变得不可维护


我很感激你的帮助。谢谢

问题解决了!我可以说:

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

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

参考您评论中的答案,我能够使静态bool属性工作

但我还是不喜欢依赖全局布尔变量,所以我决定进一步挖掘。在NHibernate3.0中,他们向配置对象添加了事件。特别是,我能够利用配置对象上的新BeforeBind事件

我稍微重写了CreateSessionFactory()方法,以展示我是如何做到这一点的

注意:在我的公式中,我总是将它们写为dbo.numpost,如果在SQLite方言中运行,事件处理程序将删除“dbo”

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.", "");
}
私有静态ISessionFactory CreateSessionFactory()
{
流畅地返回。Configure()
.Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
.Mappings(m=>m.FluentMappings
.AddFromAssembly(类型(角色).Assembly)
.Conventions.AddFromAssemblyOf())
.ExposeConfiguration(c=>
{
c、 BeforeBindMapping+=BeforeBindMappingHandler;
_配置=c;
})
.BuildConfiguration()
.BuildSessionFactory();
}
BindMappingHandler之前的私有静态void(对象发送方,BindMappingEventArgs e)
{
如果(!(e.dialogue是sqlitedialogue))返回;
var properties=e.Mapping.RootClasses
.SelectMany(r=>r.Properties)
.式中(p=>p为HbmProperty)
.Cast()
其中(p=>p.Formulas.Any());
foreach(特性中的var hbmProperty)
hbmProperty.formula=hbmProperty.formula.ToLower().Replace(“dbo.”,“”);
}

在哪里可以检测到您正在使用哪个nhibernate方言来处理是否包含“dbo.”?我在global.asax文件中设置了一个属性,例如“public static string FunctionPrefix=”dbo.;”。然后我在公式中说“dbo”的地方都用它。现在在测试中,您只需将其设置为空字符串。