在Nhibernate中使用本地SQL Server函数
本文关键字:SQL Server 函数 Nhibernate | 更新日期: 2023-09-27 18:04:08
我正在构建一个通过Nhibernate查询数据库的WPF应用程序。
我有一个SQL Server数据库的表xuser
,其中有一个标志(xflag
),存储用户的权限。
select *
from xuser
where (CONVERT(int,xflag) & 2 > 0 ) or (CONVERT(int,xflag) & 1 > 0 )
其中2 = flag_administrators
和1 = flag_superusers
如果没有SQL函数CONVERT
,这个查询不能工作,错误:
'&'操作符中的数据类型numeric和int不兼容。
现在在我的WPF c# hibernate应用程序中,我使用:
var xadmins= session.Query<Xuser>()
.Where(p => (p.Xflag & (int)Flag.FLAG_SUPERUSER)>0).ToList<string>();
这个查询不能处理相同的SQL错误。
我想在这个Linq2Nhibernate查询中使用T-SQL函数。我该怎么做呢?
最大的问题是这个应用程序必须使用MsSql2008
或Oracle
方言。如果我在这里使用Convert
函数,当我将db更改为Oracle
时,这个函数会出错。什么是最佳实践?
您可以将xflag的映射指定为公式,以便将其转换为int,即
<property name="Xflag" formula="CONVERT(int,xflag)"/>
或for Fluent NHibernate
Map(x => x.Xflag).Formula("CONVERT(int,xflag)");
然后你可以使用你的表达式来获得所有的超级用户,而不需要强制转换:
var xadmins= session.Query<Xuser>()
.Where(p => (p.Xflag & Flag.FLAG_SUPERUSER)>0).ToList<string>();
当然,这是SQL Server特有的缺点。为了在Oracle中工作,您需要使用映射:
<property name="Xflag" formula="to_number(xflag)"/>
为了解决这个问题,我们可以在两个db中创建一个用户定义函数来执行转换,这样映射就会变成:
<property name="Xflag" formula="xflag_conversion(xflag)"/>
Oracle UDF如下所示
CREATE FUNCTION xflag_conversion(xflag IN CHAR)
RETURN NUMBER
BEGIN
RETURN(to_number(xflag));
END;
SQL Server UDF应该是:
CREATE FUNCTION xflag_conversion (@xflag CHAR)
RETURNS INT
AS
BEGIN
RETURN CONVERT(int,xflag)
END
不能保证udf的准确性,因为我还没有测试过它们。
最后,这里有一个关于查询标志信息的相关问题,你可能会感兴趣:如何查询NHibernate中存储为enum的标志