我将 NHibernate 与 Firebird 一起使用,并想为 Firebird 函数创建按位与运算符 bin_and(a, b)
是这样的:
var result = customers.Where(c => (c.StatusValue & 3) > 0);
上面的查询会产生类似这样的结果:
select * from customers where (StatusValue & 3) > 0
这在 Firebird 中无效,结果应该是:
select * from customers where bin_and(StatusValue,3) > 0
是否有可能覆盖这个翻译结果?
更新
通过声明一个函数,这是可能的:
[LinqExtensionMethod("BIN_AND")] public static int BinAnd(int a, int b) { return a & b; }
var result = customers.Where(c => BinAnd(c.StatusValue, 3) > 0);
这行得通,但我正在寻找一种更通用的方法,使用“&”或“|”运算符...
更新:
@费德里克:
我这样写了自己的 Dialect 类:
public class MyFirebirdDialect: FirebirdDialect {
public MyFirebirdDialect()
{
// Bitwise operations
RegisterFunction("band", new BitwiseFunctionOperation("bin_and"));
RegisterFunction("bor", new BitwiseFunctionOperation("bin_or"));
RegisterFunction("bxor", new BitwiseFunctionOperation("bin_xor"));
RegisterFunction("bnot", new BitwiseFunctionOperation("bin_not"));
}
}
我也必须导入 BitwiseFunctionOperation.cs
如果我调试代码,我会看到这个类被用作方言,而且我看到键“band”有一个自定义函数,它的值为“bin_and”,但查询是这样的
var result = customers.Where(c => (c.StatusValue & 3) > 0);
在这样的 sql 中结束:
select * from customers where (StatusValue & 3) > 0
我认为 linq 解析器不是它的一部分......
最佳答案
您使用的是正确的方言吗? FirebirdDialect
在 HQL 中正确定义了按位和(RegisterFunction("band", new BitwiseFunctionOperation("bin_and"));
和 linq-to-nhibernate 将 &
(ExpressionType.And
) 转换为 appropriate HQL call。
如果您使用的是旧的 NHibernate 版本,也许您需要升级。
Firebird 按位运算符已添加 NH-3630在 NHibernate 4.1 中。
您可以尝试通过使用派生自 FirebirdDialect
的自定义方言在您的项目中向后移植它们,并在您的自定义方言构造函数中注册这些附加功能,如上面的链接所示。
但这行不通,因为它需要一些其他的 changes在 NHibernate 内部,在 NHibernate 4.1 之前不可用。也许通过修补 NHibernate 3.4 源代码的本地副本,您可能会成功做到这一点。
关于Nhibernate Linq & 运营商 RegisterFunction Firebird,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43889063/