0

我正在构建一个通过 Nhibernate 查询数据库的 WPF 应用程序。

我有一个 SQL Server 数据库,其中有一个表xuser,其中有一个xflag存储用户权限的标志 ()。

现在我有这个 SQL 查询来提取超级用户或管理员:

select * 
from xuser 
where (CONVERT(int,xflag) & 2 > 0 ) or (CONVERT(int,xflag) & 1 > 0 ) 

在哪里2 = flag_administrators1 = flag_superusers

如果没有 SQL 函数CONVERT,此查询将无法正常工作并出现错误:

数据类型 numeric 和 int 在 '&' 运算符中不兼容。

现在在我的 WPF c# nhibnernate 应用程序中,我查询:

var xadmins= session.Query<Xuser>()
                    .Where(p => (p.Xflag & (int)Flag.FLAG_SUPERUSER)>0).ToList<string>();

此查询不适用于相同的 SQL 错误。

我想在这个 Linq2Nhibernate 查询中使用 T-SQL 函数。我怎样才能做到这一点?

最大的问题是这个应用程序必须使用方言MsSql2008Oracle方言。如果我Convert在这里使用函数,当我将 db 更改为 时Oracle,此函数会出错。最好的做法是什么?

4

1 回答 1

2

您可以将 xflag 的映射指定为公式,以便将其转换为 int,即

<property name="Xflag" formula="CONVERT(int,xflag)"/>

或者对于 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)"/>

为了解决这个问题,可以在两个数据库中创建一个用户定义的函数来执行转换,这样映射就会变成:

<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 的准确性,因为我没有测试过它们。

最后,这里有一个您可能感兴趣的关于查询标志信息的相关问题:How to query flags stored as enum in NHibernate

于 2013-03-16T00:09:43.750 回答