Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nhibernate Linq & operator RegisterFunction Firebird

I am using NHibernate with Firebird and would like to create the bitwise and operator to the Firebird function bin_and(a, b)

Something like this:

var result = customers.Where(c => (c.StatusValue & 3) > 0);

The above query will result in something like that:

select * from customers where (StatusValue & 3) > 0

Which is not valid in Firebird, the result should be:

select * from customers where bin_and(StatusValue,3) > 0

Is there a possibility to overwrite this translated result ?

Update

By declaring a function this is possible:

  [LinqExtensionMethod("BIN_AND")]
  public static int BinAnd(int a, int b)
  {
     return a & b;
  }

var result = customers.Where(c => BinAnd(c.StatusValue, 3) > 0);

This works, but I am searching for a more generic way wizh the '&' or '|' operator...

Update:

@ Fédéric:

I wrote my own Dialect class like this:

 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"));
       }    
}

I had to import the BitwiseFunctionOperation.cs too

If I debug the code I see that this class is used as Dialect, and I see that there is a custom function for the key 'band' that has a value 'bin_and' but a Query like this

 var result = customers.Where(c => (c.StatusValue & 3) > 0);

ends up in an sql like this :

 select * from customers where (StatusValue & 3) > 0

I think the linq parser does not its part...

like image 680
Franki1986 Avatar asked Jul 13 '26 17:07

Franki1986


1 Answers

Are you using the appropriate dialect? FirebirdDialect correctly defines bitwise and in HQL (RegisterFunction("band", new BitwiseFunctionOperation("bin_and")); and linq-to-nhibernate translate & (ExpressionType.And) to the appropriate HQL call.

If you are using an old NHibernate version, maybe you need to upgrade.

Firebird bitwise operators have been added with NH-3630 in NHibernate 4.1.

You may try to back-port them in your project by using a custom dialect deriving from FirebirdDialect and registering those additional functions as illustrated in the link above, within your custom dialect constructor.

But that will not work, because it requires some other changes in NHibernate internals, not available before NHibernate 4.1. Maybe by patching a local copy of NHibernate 3.4 sources may you succeed in doing that.

like image 95
Frédéric Avatar answered Jul 15 '26 12:07

Frédéric



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!