NHibernate中的公式映射到SQLite中的函数或重写映射
我发现下面的文章可以帮助我对我的NHibernate应用程序进行单元测试。我的大多数测试都运行良好,但出现了一个奇怪的错误。从生成的SQL来看,我认为以下fluent映射导致了这些问题: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的调用,它是我的数据库中的一个用户定义函数。我知道还有其他方法可以映射这个属性,但这只是一个例子。
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”的地方都用它。现在在测试中,您只需将其设置为空字符串。