NHibernate: DB2400Dialect: Dialect does not support variable limits - nhibernate

I'm working with a S#arp Architecture project that includes some database Tasks that have worked in the past. Specifically:
var principals = _principalTasks.GetAll().AsPagination(page, limit);
where the task is defined as:
public IQueryable<Principal> GetAll()
{
return _principalRepository.FindAll().OrderBy(o => o.PrincipalName.ToLower());
}
This is effectively using NHibernate.Linq.
This is using the DB2400Dialect. Now it throws:
System.NotSupportedException: Dialect does not support variable limits.
at NHibernate.Dialect.Dialect.GetLimitString(SqlString queryString, Nullable`1 offset, Nullable`1 limit, Parameter offsetParameter, Parameter limitParameter)
at NHibernate.Hql.Ast.ANTLR.SqlGenerator.GetSqlStringWithLimitsIfNeeded(QueryWriter queryWriter)
at NHibernate.Hql.Ast.ANTLR.SqlGenerator.EndQuery()
at NHibernate.Hql.Ast.ANTLR.SqlGenerator.selectStatement()
at NHibernate.Hql.Ast.ANTLR.SqlGenerator.statement()
at NHibernate.Hql.Ast.ANTLR.HqlSqlGenerator.Generate()
.
.
.
It looks like the SQLGenerator insists on parameterizing the skip and take parameters which this dialect does not support.
Is there a way around this or is this an NHibernate bug?
EDIT:
BTW, this is the Expression Debug string from the NHibernate.Linq.DefaultQueryProvider call:
.Call System.Linq.Queryable.Take(
.Call System.Linq.Queryable.Skip(
.Call System.Linq.Queryable.OrderBy(
.Constant<NHibernate.Linq.NhQueryable`1[SolutionExample.Domain.Principal]>(NHibernate.Linq.NhQueryable`1[SolutionExample.Domain.Principal]),
'(.Lambda #Lambda1<System.Func`2[SolutionExample.Domain.Principal,System.String]>)),
0),
25)
.Lambda #Lambda1<System.Func`2[SolutionExample.Domain.Principal,System.String]>(SolutionExample.Domain.Principal $o) {
.Call ($o.PrincipalName).ToLower()
}

After much research I've decided that while I could solve this question by either creating my own custom dialect that implements - or extending the existing DB2400Dialect to implement -
public SqlString GetLimitString(SqlString queryString, int? offset, int? limit, Parameter offsetParameter, Parameter limitParameter)
that would be pointless since while the iSeries allows a limit with the
... FETCH FIRST n ROWS ONLY
syntax, it has no equivalent syntax for doing an offset... so, there isn't much point to fixing the broken bits.

Related

Adding a Dapper Dynamic Output Parameter in VB.NET

I'm trying to use Dapper to call a stored procedure that has a couple Output parameters, using VB.NET (and .NET 4.0).
However, it seems I cannot use the DynamicParameters.Add method, because I'm getting the following compiler error:
'Add' is ambiguous because multiple kinds of members with this name
exist in class 'Dapper.DynamicParameters'.
...when I try to write the following line:
p.Add("#NewRecordID", DbType:=DbType.Int32, direction:=ParameterDirection.Output)
A quick search tells me this sometimes happens when using a C# library that has multiple methods that differ only in name case (VB.NET being case-insensitive). Searching the Dapper source code for DynamicParameters does show the following two overloads for the Add method, but they both use the same case, and the compiler should be able to discern between the two.
public void Add(string name, object value, DbType? dbType, ParameterDirection? direction, int? size)
public void Add(string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null, byte? precision = null, byte? scale = null)
(I've also tried adding scale:=Nothing to the call to force the second overload, to no avail.)
While I can work around this with the input parameters by passing in an anonymous object to the DynamicParameters constructor, I can't find a way around this when adding the output parameters.
I've checked the project references to ensure there aren't multiple or ambiguous assembly references.
Has anybody encountered this problem before, and found a workaround?
At the moment, the only option I can think of is to re-write the stored procedure call without using Dapper, as implied here.
From what I can gather, the following are all potential solutions:
Rewrite the Stored Procedure to not use Output parameters. (The option I was able to use in this case.)
Rewrite the code calling the Stored Procedure to use standard ADO.NET.
Rewrite Dapper to use a different overload pattern for DynamicParameters.Add.
Update the project to use .NET 4.5.
Reimplement IDynamicParameter(s) or possibly subclass DynamicParameters

cli/c++ increment operator overloading

i have a question regarding operator overloading in cli/c++ environment
static Length^ operator++(Length^ len)
{
Length^ temp = gcnew Length(len->feet, len->inches);
++temp->inches;
temp->feet += temp->inches/temp->inchesPerFoot;
temp->inches %= temp->inchesPerFoot;
return temp;
}
(the code is from ivor horton's book.)
why do we need to declare a new class object (temp) on the heap just to return it?
ive googled for the info on overloading but theres really not much out there and i feel kinda lost.
This is the way operator overloading is implemented in .NET. Overloaded operator is static function, which returns a new instance, instead of changing the current instance. Therefore, post and prefix ++ operators are the same. Most information about operator overloading talks about native C++. You can see .NET specific information, looking for C# samples, for example this: http://msdn.microsoft.com/en-us/library/aa288467(v=vs.71).aspx
.NET GC allows to create a lot of lightweight new instances, which are collected automatically. This is why .NET overloaded operators are more simple than in native C++.
Yes, because you're overloading POST-increment operator here. Hence, the original value may be used a lot in the code, copied and stored somewhere else, despite the existance of the new value. Example:
store_length_somewhere( len++ );
While len will be increased, the original value might be stored by the function somewhere else. That means that you might need two different values at the same time. Hence the creation and return of a new value.

NHibernate ISQLQuery SetParameter issue

This is probably fairly straightforward but i can't seem to find a reasonable explanation in any documentation.
I'm trying to use an NHibernate.ISQLQuery and using SetResultTransformer() to return a custom set of results from a custom SQL query. Like so:
public virtual IList<T> GetSQLObject<T>(string sql, IDbParameter[] parameters = null)
{
ISQLQuery qry = _sess.CreateSQLQuery(sql);
qry.SetResultTransformer(Transformers.AliasToBean(typeof(T)));
if (parameters != null) {
foreach (IDbParameter parameter in parameters) {
qry.SetParameter(parameter.Name, parameter.Value);
}
}
return qry.List<T>();
}
From looking at the examples, it seems that in the sql query I have to use parameters in the format :param1 instead of #param1 as I would in a standard SQL query. If i use the latter syntax in the query, it throws an error at qry.SetParameter().
Is there a reason why ISQLQuery/NHibernate requires them in this format and won't work with the normal syntax?
SQL Server uses #param, but not every other database does. For example, MySQL uses ?param
NHibernate allows you to swap out 1 database implementation for another with little to no reworking of your DAL. It sets the parameters based on the database you configured when you setup the NH Configuration.
Edit: Also I think :param came about from Hibernate being targeted at Oracle when it was initially developed, since Oracle uses :param
Phil has answered the "why"; so perhaps I can recommend a "how"; why not just add a new extension method to the IDbParameter type (something like .GetNHibernateName() ) that will return the parameter name with the "#" replaced with a ":"; that should be trivial to implement.

Convert MethodBody to Expression Tree

Is there a way to convert a MethodBody (or other Reflection technique) into a System.Linq.Expressions.Expression tree?
It is indeed possible, see DelegateDecompiler:
https://github.com/hazzik/DelegateDecompiler
NOTE: I am not affiliated with this project
Edit
Here is the basic approach that the project takes:
Get MethodInfo for the method you want to convert
Use methodInfo.GetMethodBody to get a MethodBody object. This contains,
among other things, the MSIL and info on arguments and locals
Go through the instructions, examine the opcodes, and build the appropriate Expressions
Tie it all together and return an optimized Expression
Here is a code snippet from the project that decompiles a method body:
public class MethodBodyDecompiler
{
readonly IList<Address> args;
readonly VariableInfo[] locals;
readonly MethodInfo method;
public MethodBodyDecompiler(MethodInfo method)
{
this.method = method;
var parameters = method.GetParameters();
if (method.IsStatic)
args = parameters
.Select(p => (Address) Expression.Parameter(p.ParameterType, p.Name))
.ToList();
else
args = new[] {(Address) Expression.Parameter(method.DeclaringType, "this")}
.Union(parameters.Select(p => (Address) Expression.Parameter(p.ParameterType, p.Name)))
.ToList();
var body = method.GetMethodBody();
var addresses = new VariableInfo[body.LocalVariables.Count];
for (int i = 0; i < addresses.Length; i++)
{
addresses[i] = new VariableInfo(body.LocalVariables[i].LocalType);
}
locals = addresses.ToArray();
}
public LambdaExpression Decompile()
{
var instructions = method.GetInstructions();
var ex = Processor.Process(locals, args, instructions.First(), method.ReturnType);
return Expression.Lambda(new OptimizeExpressionVisitor().Visit(ex), args.Select(x => (ParameterExpression) x.Expression));
}
}
No, there isn't.
You're basically asking for a somewhat simpler version of Reflector.
Yes, it is possible... but it hasn't been done yet, as far as I know.
If anyone does know of a library that de-compiles methods to expression trees, please let me know, or edit the above statement.
The most difficult part of what you would have to do is write a CIL de-compiler. That is, you would need to translate the fairly low-level CIL instructions (which conceptually target a stack machine) into much higher-level expressions.
Tools such as Redgate's Reflector or Telerik's JustDecompile do just that, but instead of building expression trees, they display source code; you could say they go one step further, since expression trees are basically still language-agnostic.
Some notable cases where this would get especially tricky:
You would have to deal with cases of CIL instructions for which no pre-defined Expression tree node exists; let's say, tail.call, or cpblk (I'm guessing a little here). That is, you'd have to create custom expression tree node types; having them compiled back into an executable method when you .Compile() the expression tree might be an issue, because the expression tree compiler tries to break down custom nodes into standard nodes. If that is not possible, then you cannot compile the expression tree any more, you could only inspect it.
Would you try to recognise certain high-level constructs, such as a C# using block, and try to build a (custom) expression tree node for it? Remember that C# using breaks down to the equivalent of try…finally { someObj.Dispose(); } during compilation, so that is what you might see instead of using if you reflected over the method body's CIL instructions and exception handling clauses.
Thus, in general, expect that you need to be able to "recognise" certain code patterns and summarise them into a higher-level concept.

Is it possible to do Standard Deviation in NHibernate?

Is it possible to calculate Standard Deviation with NHibernate? I'm using the Microsoft SQL Server 2005 Dialect.
I can't find any examples of this anywhere.
Please help.
thanks!
Just wanted to let everyone know how I accomplished this with code that may help others:
When I create my SessionFactory, I simply add a custom SQL Function to the Configuration Object:
Setup:
var configuration = new Configuration();
configuration.AddSqlFunction("stdev", new StandardSQLFunction("stdev", HibernateUtil.Double));
SessionFactory = configuration.Configure().BuildSessionFactory();
Usage:
Then in my data provider I now can call the custom function:
ICriteria criteria = _session.CreateCriteria(typeof(ItemHistory));
criteria.SetProjection(Projections.SqlFunction("stdev", NHibernateUtil.Double, Projections.Property("Speed") ));
IList results = criteria.List();
I'm not that familiar with NHibernate, but using the Java Hibernate you can subclass an existing dialect easily to add extra functions. Something like this might do the trick for you (this is the Java version):
public class MyDialect extends SQLServerDialect
{
public MyDialect()
{
super();
// register extra functions (may need to specify parameter types)
registerFunction( "stdev", new StandardSQLFunction( "stdev" ) );
}
}
STDEV is a native SQL function for SQL Server... can you pass through a native query?
You can use native SQL queries, including aggregate functions, in HQL (Hibernate Query Language). See Chapter 12 in the documentation.
Edited to add: I just read it myself and STDEV is not supported. An alternative that might work is to create a view that includes the calculation and map the view instead of the table. Further Googling leads me to believe that the documentation may be out of date or there are extensions to NHibernate that include STDEV.
I've solved in a more standard way by this code:
sqrt((sum(value*value)/count(value)) - (avg(value) * avg(value)))
In other way, unrolling the formula of the standard deviation using the other aggregate functions that are supported: sum and count.
I've checked against the formula 'std()' in mysql and this works except by the least significant digits (error less of 0.000000001D).