From: <fab...@us...> - 2011-05-22 22:44:52
|
Revision: 5857 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5857&view=rev Author: fabiomaulo Date: 2011-05-22 22:44:45 +0000 (Sun, 22 May 2011) Log Message: ----------- Fix NH-2702 (ready for refactoring but after fix all others related issues) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs trunk/nhibernate/src/NHibernate.Test/Hql/Ast/LimitClauseFixture.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -1680,6 +1680,17 @@ get { return false; } } + public virtual SqlString GetLimitString(SqlString querySqlString, int offset, int limit, Parameter offsetParameter, Parameter limitParameter) + { + if (!SupportsVariableLimit) + return GetLimitString(querySqlString, offset, limit); + + if ((offsetParameter == null) && (limitParameter == null)) + return GetLimitString(querySqlString, offset, limit); + + throw new NotSupportedException("Override to support limits passed as parameters"); + } + /// <summary> /// Add a <c>LIMIT</c> clause to the given SQL <c>SELECT</c> /// when the dialect supports variable limits (i.e. parameters for the limit constraints) @@ -1687,8 +1698,8 @@ /// <param name="querySqlString">The <see cref="SqlString"/> to base the limit query off.</param> /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offsetParameterIndex">Optionally, the Offset parameter index</param> - /// <param name="limitParameterIndex">Optionally, the Limit parameter index</param> + /// <param name="offsetParameterIndex">Optionally, the Offset parameter index in the sql</param> + /// <param name="limitParameterIndex">Optionally, the Limit parameter index in the sql</param> /// <returns>A new <see cref="SqlString"/> that contains the <c>LIMIT</c> clause.</returns> public virtual SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) { Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -42,23 +42,36 @@ /// <param name="querySqlString">The <see cref="SqlString"/> to base the limit query off.</param> /// <param name="offset">Offset of the first row to be returned by the query (zero-based)</param> /// <param name="limit">Maximum number of rows to be returned by the query</param> - /// <param name="offsetParameterIndex">Optionally, the Offset parameter index</param> - /// <param name="limitParameterIndex">Optionally, the Limit parameter index</param> + /// <param name="offsetParameterIndex">Optionally, the Offset parameter index in the sql</param> + /// <param name="limitParameterIndex">Optionally, the Limit parameter index in the sql</param> /// <returns>A new <see cref="SqlString"/> with the <c>LIMIT</c> clause applied.</returns> /// <remarks> /// Note that we need to explicitly specify the columns, because we need to be able to use them in a paged subselect [NH-1155] /// </remarks> public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, int? offsetParameterIndex, int? limitParameterIndex) { - object limitObject = limitParameterIndex == null ? Parameter.Placeholder : Parameter.WithIndex(limitParameterIndex.Value); - object offsetObject = null; - if (offset != 0) - offsetObject = offsetParameterIndex == null ? Parameter.Placeholder : Parameter.WithIndex(offsetParameterIndex.Value); - return GetLimitString(querySqlString, offsetObject, limitObject); + object limitObject = limitParameterIndex == null ? (object) new SqlString(limit.ToString()) : Parameter.WithIndex(limitParameterIndex.Value); + object offsetObject = null; + if (offset != 0) + { + offsetObject = offsetParameterIndex == null ? (object) new SqlString(offset.ToString()) : Parameter.WithIndex(offsetParameterIndex.Value); + } + return GetLimitString(querySqlString, offsetObject, limitObject); } - private SqlString GetLimitString(SqlString querySqlString, object offset, object limit) + public override SqlString GetLimitString(SqlString querySqlString, int offset, int limit, Parameter offsetParameter, Parameter limitParameter) { + object limitObject = limitParameter ?? (object) new SqlString(limit.ToString()); + object offsetObject = null; + if (offset != 0) + { + offsetObject = offsetParameter ?? (object) new SqlString(offset.ToString()); + } + return GetLimitString(querySqlString, offsetObject, limitObject); + } + + private SqlString GetLimitString(SqlString querySqlString, object offset, object limit) + { if (offset == null && limit == null) return querySqlString; Modified: trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -487,7 +487,7 @@ int span = typedval.Type.GetColumnSpan(factory); string name = namedParameter.Key; - int[] locs = getNamedParameterLocations(name); + int[] locs = GetEffectiveNamedParameterLocations(sqlParameters, name) ?? getNamedParameterLocations(name); for (int i = 0; i < locs.Length; i++) { int location = locs[i]; @@ -567,6 +567,23 @@ return ConvertITypesToSqlTypes(paramTypeList, factory, totalSpan); } + private int[] GetEffectiveNamedParameterLocations(IList<Parameter> sqlParameters, string name) + { + var locations = new List<int>(5); + for (int i = 0; i < sqlParameters.Count; i++) + { + if(name.Equals(sqlParameters[i].BackTrack)) + { + locations.Add(i); + } + } + if(locations.Count == 0) + { + return null; + } + return locations.ToArray(); + } + public int BindParameters(IDbCommand command, int start, ISessionImplementor session) { int location = start; Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -129,9 +129,20 @@ private void Out(IASTNode n) { - if (n is ParameterNode) + var parameterNode= n as ParameterNode; + if (parameterNode != null) { - ParameterOut(); + var namedParameterSpecification = parameterNode.HqlParameterSpecification as NamedParameterSpecification; + if(namedParameterSpecification != null) + { + var parameter = Parameter.Placeholder; + parameter.BackTrack = namedParameterSpecification.Name; + writer.PushParameter(parameter); + } + else + { + ParameterOut(); + } } else if (n is SqlNode) { @@ -142,9 +153,9 @@ Out(n.Text); } - if (n is ParameterNode) + if (parameterNode != null) { - collectedParameters.Add(((ParameterNode) n).HqlParameterSpecification); + collectedParameters.Add(parameterNode.HqlParameterSpecification); } else if (n is IParameterContainer) { @@ -318,35 +329,78 @@ private void EndQuery() { - var queryWriter = ((QueryWriter) writer); - SqlString sqlString = queryWriter.ToSqlString(); + SqlString sqlString = GetSqlStringWithLimitsIfNeeded((QueryWriter) writer); - if (queryWriter.Take.HasValue || queryWriter.Skip.HasValue) - { - sqlString = sessionFactory.Dialect.GetLimitString(sqlString, queryWriter.Skip ?? 0, queryWriter.Take ?? int.MaxValue); - } - writer = outputStack[0]; outputStack.RemoveAt(0); Out(sqlString); } + private SqlString GetSqlStringWithLimitsIfNeeded(QueryWriter queryWriter) + { + SqlString sqlString = queryWriter.ToSqlString(); + var skipIsParameter = queryWriter.SkipParameter != null; + var takeIsParameter = queryWriter.TakeParameter != null; + var hqlQueryHasLimits = queryWriter.Take.HasValue || queryWriter.Skip.HasValue || skipIsParameter || takeIsParameter; + if (!hqlQueryHasLimits) + { + return sqlString; + } + + var dialect = sessionFactory.Dialect; + + var hqlQueryHasFixedLimits = (queryWriter.Take.HasValue || queryWriter.Skip.HasValue) && !skipIsParameter && !takeIsParameter; + if(hqlQueryHasFixedLimits) + { + return dialect.GetLimitString(sqlString, queryWriter.Skip ?? 0, queryWriter.Take ?? int.MaxValue); + } + // Skip-Take in HQL should be supported just for Dialect supporting variable limits at least when users use parameters for skip-take. + if (!dialect.SupportsVariableLimit && (skipIsParameter || takeIsParameter)) + { + throw new NotSupportedException("The dialect " + dialect.GetType().FullName + " does not supports variable limits"); + } + // At this point at least one of the two limits is a parameter and that parameter should be of IExplicitValueParameterSpecification + Parameter skipParameter = null; + Parameter takeParameter = null; + if(queryWriter.SkipParameter != null) + { + skipParameter = Parameter.Placeholder; + skipParameter.BackTrack = queryWriter.SkipParameter.Name; + } + if (queryWriter.TakeParameter != null) + { + takeParameter = Parameter.Placeholder; + takeParameter.BackTrack = queryWriter.TakeParameter.Name; + } + + sqlString = dialect.GetLimitString(sqlString, skipIsParameter ? 1 : queryWriter.Skip ?? 0, queryWriter.Take ?? int.MaxValue, skipParameter, takeParameter); + return sqlString; + } + private void Skip(IASTNode node) { - if (node is ParameterNode) + var queryWriter = (QueryWriter)writer; + var pnode = node as ParameterNode; + if (pnode != null) { - throw new NotSupportedException("Parameter limits is not supported yet."); + queryWriter.SkipParameter = (NamedParameterSpecification) pnode.HqlParameterSpecification; + collectedParameters.Add(pnode.HqlParameterSpecification); + return; } - ((QueryWriter) writer).Skip = Convert.ToInt32(node.Text); + queryWriter.Skip = Convert.ToInt32(node.Text); } private void Take(IASTNode node) { - if (node is ParameterNode) + var queryWriter = (QueryWriter)writer; + var pnode = node as ParameterNode; + if (pnode != null) { - throw new NotSupportedException("Parameter limits is not supported yet."); + queryWriter.TakeParameter = (NamedParameterSpecification)pnode.HqlParameterSpecification; + collectedParameters.Add(pnode.HqlParameterSpecification); + return; } - ((QueryWriter) writer).Take = Convert.ToInt32(node.Text); + queryWriter.Take = Convert.ToInt32(node.Text); } #region Nested type: DefaultWriter @@ -380,6 +434,11 @@ generator.GetStringBuilder().AddParameter(); } + public void PushParameter(Parameter parameter) + { + generator.GetStringBuilder().Add(parameter); + } + public void CommaBetweenParameters(String comma) { generator.GetStringBuilder().Add(comma); @@ -399,8 +458,13 @@ { private readonly SqlStringBuilder builder = new SqlStringBuilder(); - #region ISqlWriter Members + public NamedParameterSpecification TakeParameter { get; set; } + public NamedParameterSpecification SkipParameter { get; set; } + public int? Skip { get; set; } + public int? Take { get; set; } + #region ISqlWriter Members + public void Clause(String clause) { builder.Add(clause); @@ -416,7 +480,12 @@ builder.AddParameter(); } - public void CommaBetweenParameters(String comma) + public void PushParameter(Parameter parameter) + { + builder.Add(parameter); + } + + public void CommaBetweenParameters(String comma) { builder.Add(comma); } @@ -426,8 +495,6 @@ return builder.ToSqlString(); } - public int? Skip { get; set; } - public int? Take { get; set; } #endregion } @@ -489,6 +556,18 @@ } } + public void PushParameter(Parameter parameter) + { + if (argInd == args.Count) + { + args.Add(new SqlString(parameter)); + } + else + { + args[argInd] = args[argInd].Append(new SqlString(parameter)); + } + } + public void CommaBetweenParameters(string comma) { ++argInd; @@ -509,6 +588,7 @@ void Clause(string clause); void Clause(SqlString clause); void Parameter(); + void PushParameter(Parameter parameter); /** * todo remove this hack * The parameter is either ", " or " , ". This is needed to pass sql generating tests as the old Modified: trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -18,6 +18,7 @@ /// </summary> public int? ParameterPosition; + public object BackTrack { get; set; } /// <summary> /// Used as a placeholder when parsing HQL or SQL queries. /// </summary> @@ -34,6 +35,11 @@ return new Parameter() { ParameterPosition = position }; } + public Parameter Clone() + { + return new Parameter { BackTrack = this.BackTrack }; + } + private Parameter() { } Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -580,10 +580,11 @@ for (int i=0; i<clone.sqlParts.Length; i++) { - if (clone.sqlParts[i] is Parameter) + var parameter = clone.sqlParts[i] as Parameter; + if (parameter != null) { - var originalParameter = (Parameter)clone.sqlParts[i]; - var copyParameter = SqlCommand.Parameter.Placeholder; + var originalParameter = parameter; + var copyParameter = originalParameter.Clone(); if (originalParameter.ParameterPosition < 0) { Modified: trunk/nhibernate/src/NHibernate.Test/Hql/Ast/LimitClauseFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Hql/Ast/LimitClauseFixture.cs 2011-05-22 22:43:01 UTC (rev 5856) +++ trunk/nhibernate/src/NHibernate.Test/Hql/Ast/LimitClauseFixture.cs 2011-05-22 22:44:45 UTC (rev 5857) @@ -1,155 +1,177 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; using NHibernate.Hql.Ast.ANTLR; using NUnit.Framework; +using SharpTestsEx; namespace NHibernate.Test.Hql.Ast { - [TestFixture] - public class LimitClauseFixture : BaseFixture - { - protected override void OnSetUp() - { - ISession session = OpenSession(); - ITransaction txn = session.BeginTransaction(); + [TestFixture] + public class LimitClauseFixture : BaseFixture + { + protected override bool AppliesTo(Dialect.Dialect dialect) + { + return dialect.SupportsVariableLimit; + } - var mother = new Human { BodyWeight = 10, Description = "mother" }; - var father = new Human { BodyWeight = 15, Description = "father" }; - var child1 = new Human { BodyWeight = 5, Description = "child1" }; - var child2 = new Human { BodyWeight = 6, Description = "child2" }; - var friend = new Human { BodyWeight = 20, Description = "friend" }; + protected override void OnSetUp() + { + ISession session = OpenSession(); + ITransaction txn = session.BeginTransaction(); - session.Save(mother); - session.Save(father); - session.Save(child1); - session.Save(child2); - session.Save(friend); + var mother = new Human {BodyWeight = 10, Description = "mother"}; + var father = new Human {BodyWeight = 15, Description = "father"}; + var child1 = new Human {BodyWeight = 5, Description = "child1"}; + var child2 = new Human {BodyWeight = 6, Description = "child2"}; + var friend = new Human {BodyWeight = 20, Description = "friend"}; - txn.Commit(); - session.Close(); - } + session.Save(mother); + session.Save(father); + session.Save(child1); + session.Save(child2); + session.Save(friend); - protected override void OnTearDown() - { - ISession session = OpenSession(); - ITransaction txn = session.BeginTransaction(); + txn.Commit(); + session.Close(); + } + + protected override void OnTearDown() + { + ISession session = OpenSession(); + ITransaction txn = session.BeginTransaction(); session.Delete("from Animal"); - txn.Commit(); - session.Close(); - } + txn.Commit(); + session.Close(); + } - [Test] - public void None() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void None() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight").List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 5, 6, 10, 15, 20 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight").List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {5, 6, 10, 15, 20}; + CollectionAssert.AreEqual(expected, actual); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test] - public void Skip() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void Skip() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h where h.bodyWeight > :minW order by h.bodyWeight skip 2").SetDouble("minW", 0d).List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 10, 15, 20 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h where h.bodyWeight > :minW order by h.bodyWeight skip 2").SetDouble("minW", 0d).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {10, 15, 20}; + CollectionAssert.AreEqual(expected, actual); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test, Ignore("Not supported yet.")] - public void SkipWithParameter() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void SkipTake() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight skip :jump").SetInt32("jump", 2).List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 10, 15, 20 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight skip 1 take 3").List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {6, 10, 15}; + CollectionAssert.AreEqual(expected, actual); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test] - public void Take() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void SkipTakeWithParameter() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight take 2").List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 5, 6 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight skip :pSkip take :pTake") + .SetInt32("pSkip", 1) + .SetInt32("pTake", 3).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {6f, 10f, 15f}; + actual.Should().Have.SameSequenceAs(expected); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test, Ignore("Not supported yet.")] - public void TakeWithParameter() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void SkipTakeWithParameterList() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight take :jump").SetInt32("jump", 2).List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 5, 6 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h where h.bodyWeight in (:list) order by h.bodyWeight skip :pSkip take :pTake") + .SetParameterList("list", new[] {10f, 15f, 5f}) + .SetInt32("pSkip", 1) + .SetInt32("pTake", 4).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {10f, 15f}; + actual.Should().Have.SameSequenceAs(expected); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test] - public void SkipTake() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void SkipWithParameter() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight skip 1 take 3").List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 6, 10, 15 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight skip :jump").SetInt32("jump", 2).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {10f, 15f, 20f}; + actual.Should().Have.SameSequenceAs(expected); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test, Ignore("Not supported yet.")] - public void SkipTakeWithParameter() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void Take() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - var actual = s.CreateQuery("from Human h order by h.bodyWeight skip :pSkip take :pTake") - .SetInt32("pSkip", 1) - .SetInt32("pTake", 3).List<Human>().Select(h => h.BodyWeight).ToArray(); - var expected = new[] { 6, 10, 15 }; - CollectionAssert.AreEqual(expected, actual); + float[] actual = s.CreateQuery("from Human h order by h.bodyWeight take 2").List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {5, 6}; + CollectionAssert.AreEqual(expected, actual); - txn.Commit(); - s.Close(); - } + txn.Commit(); + s.Close(); + } - [Test] - public void TakeSkip() - { - ISession s = OpenSession(); - ITransaction txn = s.BeginTransaction(); + [Test] + public void TakeSkip() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); - Assert.Throws<QuerySyntaxException>(() => s.CreateQuery("from Human h order by h.bodyWeight take 1 skip 2").List<Human>(), "take should not be allowed before skip"); + Assert.Throws<QuerySyntaxException>(() => s.CreateQuery("from Human h order by h.bodyWeight take 1 skip 2").List<Human>(), "take should not be allowed before skip"); - txn.Commit(); - s.Close(); - } - } -} + txn.Commit(); + s.Close(); + } + + [Test] + public void TakeWithParameter() + { + ISession s = OpenSession(); + ITransaction txn = s.BeginTransaction(); + + float[] actual = s.CreateQuery("from Human h where h.bodyWeight > :minW order by h.bodyWeight take :jump") + .SetDouble("minW", 1d) + .SetInt32("jump", 2).List<Human>().Select(h => h.BodyWeight).ToArray(); + var expected = new[] {5, 6}; + CollectionAssert.AreEqual(expected, actual); + + txn.Commit(); + s.Close(); + } + } +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |