diff --git a/src/NHibernate.Test/Linq/ParameterisedQueries.cs b/src/NHibernate.Test/Linq/ParameterisedQueries.cs index 21d0455a1fe..298862fef3f 100644 --- a/src/NHibernate.Test/Linq/ParameterisedQueries.cs +++ b/src/NHibernate.Test/Linq/ParameterisedQueries.cs @@ -5,6 +5,7 @@ using System.Linq.Expressions; using NHibernate.Linq; using NHibernate.DomainModel.Northwind.Entities; +using NHibernate.Type; using NUnit.Framework; namespace NHibernate.Test.Linq @@ -55,6 +56,32 @@ public void Expressions_Differing_Only_By_Constants_Return_The_Same_Key() } } + [Test] + public void CanSpecifyParameterTypeInfo() + { + using (var s = OpenSession()) + { + var db = new Northwind(s); + + Expression>> london = + () => from c in db.Customers where c.Address.City == "London".MappedAs(NHibernateUtil.StringClob) select c; + + Expression>> newYork = + () => from c in db.Customers where c.Address.City == "New York".MappedAs(NHibernateUtil.AnsiString) select c; + + var nhLondon = new NhLinqExpression(london.Body, sessions); + var nhNewYork = new NhLinqExpression(newYork.Body, sessions); + + var londonParameter = nhLondon.ParameterValuesByName.Single().Value; + Assert.That(londonParameter.Item1, Is.EqualTo("London")); + Assert.That(londonParameter.Item2, Is.EqualTo(NHibernateUtil.StringClob)); + + var newYorkParameter = nhNewYork.ParameterValuesByName.Single().Value; + Assert.That(newYorkParameter.Item1, Is.EqualTo("New York")); + Assert.That(newYorkParameter.Item2, Is.EqualTo(NHibernateUtil.AnsiString)); + } + } + [Test] public void Different_Where_Clauses_Return_Different_Keys() { diff --git a/src/NHibernate/Linq/LinqExtensionMethods.cs b/src/NHibernate/Linq/LinqExtensionMethods.cs index e9ee33324f0..4ced1269873 100755 --- a/src/NHibernate/Linq/LinqExtensionMethods.cs +++ b/src/NHibernate/Linq/LinqExtensionMethods.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Linq.Expressions; using NHibernate.Impl; +using NHibernate.Type; using Remotion.Linq; using Remotion.Linq.Parsing.ExpressionTreeVisitors; @@ -47,7 +48,6 @@ public static IQueryable CacheRegion(this IQueryable query, string regi return new NhQueryable(query.Provider, callExpression); } - public static IQueryable Timeout(this IQueryable query, int timeout) { var method = ReflectionHelper.GetMethodDefinition(() => Timeout(null, 0)).MakeGenericMethod(typeof(T)); @@ -84,6 +84,11 @@ public static IFutureValue ToFutureValue(this IQueryable query) return (IFutureValue) future; } + public static T MappedAs(this T parameter, IType type) + { + throw new InvalidOperationException("The method should be used inside Linq to indicate a type of a parameter"); + } + public static IFutureValue ToFutureValue(this IQueryable query, Expression, TResult>> selector) { var nhQueryable = query as QueryableBase; diff --git a/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs b/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs index cb4c82c90f4..01c9cb6c1a5 100644 --- a/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs +++ b/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -8,7 +7,6 @@ using NHibernate.Param; using NHibernate.Type; using Remotion.Linq.Parsing; -using Remotion.Linq.Utilities; namespace NHibernate.Linq.Visitors { @@ -44,6 +42,16 @@ public static IDictionary Visit(Expression e protected override Expression VisitMethodCallExpression(MethodCallExpression expression) { + if (expression.Method.Name == "MappedAs" && expression.Method.DeclaringType == typeof(LinqExtensionMethods)) + { + var parameter = (ConstantExpression) VisitExpression(expression.Arguments[0]); + var type = (ConstantExpression) expression.Arguments[1]; + + _parameters[parameter].Type = (IType) type.Value; + + return parameter; + } + var method = expression.Method.IsGenericMethod ? expression.Method.GetGenericMethodDefinition() : expression.Method; diff --git a/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionTreeVisitor.cs b/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionTreeVisitor.cs index 94d29da9c10..462051d75b9 100644 --- a/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionTreeVisitor.cs +++ b/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionTreeVisitor.cs @@ -1,10 +1,11 @@ using System.Linq.Expressions; +using Remotion.Linq.Clauses.Expressions; using Remotion.Linq.Parsing; using Remotion.Linq.Parsing.ExpressionTreeVisitors; namespace NHibernate.Linq.Visitors { - internal class NhPartialEvaluatingExpressionTreeVisitor : ExpressionTreeVisitor + internal class NhPartialEvaluatingExpressionTreeVisitor : ExpressionTreeVisitor, IPartialEvaluationExceptionExpressionVisitor { protected override Expression VisitConstantExpression(ConstantExpression expression) { @@ -22,5 +23,10 @@ public static Expression EvaluateIndependentSubtrees(Expression expression) var evaluatedExpression = PartialEvaluatingExpressionTreeVisitor.EvaluateIndependentSubtrees(expression); return new NhPartialEvaluatingExpressionTreeVisitor().VisitExpression(evaluatedExpression); } + + public Expression VisitPartialEvaluationExceptionExpression(PartialEvaluationExceptionExpression expression) + { + return VisitExpression(expression.Reduce()); + } } } \ No newline at end of file