references info c# sql-server nhibernate sql-server-2016

c# - references - nhibernate info



NHibernate HQL Generator para soportar las tablas temporales de SQL Server 2016 (1)

Estoy intentando implementar soporte básico para las tablas temporales de SQL Server 2016 en NHibernate 4.x. La idea es alterar la sentencia SQL desde

SELECT * FROM Table t0

a

SELECT * FROM Table FOR SYSTEM_TIME AS OF ''2018-01-16 00:00:00'' t0

Puede encontrar más información sobre las tablas temporales en SQL Server 2016 here

Desafortunadamente, no he encontrado ninguna forma de insertar la FOR FOR SYSTEM_TIME AS OF ''...'' entre el nombre de la tabla y su alias. No estoy seguro de si los dialectos personalizados son compatibles con esto. La única solución funcional que tengo por ahora es agregar la declaración FOR SYSTEM_TIME dentro de WHERE extra y mi resultado de SQL se ve así.

SELECT * FROM Table t0 WHERE FOR SYSTEM_TIME AS OF ''2018-01-16 00:00:00''=1

Para ello, he implementado generador y dialecto de la siguiente manera:

public static class AuditableExtensions { public static bool AsOf(this IAuditable entity, DateTime date) { return true; } public static IQueryable<T> Query<T>(this ISession session, DateTime asOf) where T : IAuditable { return session.Query<T>().Where(x => x.AsOf(asOf)); } } public class ForSystemTimeGenerator : BaseHqlGeneratorForMethod { public static readonly string ForSystemTimeAsOfString = "FOR SYSTEM_TIME AS OF"; public ForSystemTimeGenerator() { SupportedMethods = new[] { ReflectionHelper.GetMethod(() => AuditableExtensions.AsOf(null, DateTime.MinValue)) }; } public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) { return treeBuilder.BooleanMethodCall(nameof(AuditableExtensions.AsOf), new[] { visitor.Visit(arguments[1]).AsExpression() }); } } public class MsSql2016Dialect : MsSql2012Dialect { public MsSql2016Dialect() { RegisterFunction(nameof(AuditableExtensions.AsOf), new SQLFunctionTemplate( NHibernateUtil.Boolean, $"{ForSystemTimeGenerator.ForSystemTimeAsOfString} ?1?2=1")); } }

¿Puede alguien proporcionar un mejor enfoque o ejemplos que pueda usar para avanzar e insertar la FOR SYSTEM_TIME AS OF entre el nombre de la tabla y su alias? En este momento, la única solución que puedo ver es alterar SQL en OnPrepareStatement en SessionInterceptor pero creo que hay un mejor enfoque ...


DECLARE @String1 NVARCHAR(100), @String2 NVARCHAR(100) , @DateTime DATETIME= ''2018-01-16 00:00:00''; SET @String1 = ''SELECT * FROM Table2''; SET @String2 = @String1 + '' FOR SYSTEM_TIME AS OF '''''' + CONVERT(VARCHAR(20), @DateTime, 120) + ''''''''; SELECT @String2;