Skip to content

Commit 693f298

Browse files
committed
NH-2401 - A method to specify IType of LINQ parameter
1 parent e1d6992 commit 693f298

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

src/NHibernate.Test/Linq/ParameterisedQueries.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq.Expressions;
66
using NHibernate.Linq;
77
using NHibernate.DomainModel.Northwind.Entities;
8+
using NHibernate.Type;
89
using NUnit.Framework;
910

1011
namespace NHibernate.Test.Linq
@@ -55,6 +56,32 @@ public void Expressions_Differing_Only_By_Constants_Return_The_Same_Key()
5556
}
5657
}
5758

59+
[Test]
60+
public void CanSpecifyParameterTypeInfo()
61+
{
62+
using (var s = OpenSession())
63+
{
64+
var db = new Northwind(s);
65+
66+
Expression<Func<IEnumerable<Customer>>> london =
67+
() => from c in db.Customers where c.Address.City == "London".MappedAs(NHibernateUtil.StringClob) select c;
68+
69+
Expression<Func<IEnumerable<Customer>>> newYork =
70+
() => from c in db.Customers where c.Address.City == "New York".MappedAs(NHibernateUtil.AnsiString) select c;
71+
72+
var nhLondon = new NhLinqExpression(london.Body, sessions);
73+
var nhNewYork = new NhLinqExpression(newYork.Body, sessions);
74+
75+
var londonParameter = nhLondon.ParameterValuesByName.Single().Value;
76+
Assert.That(londonParameter.Item1, Is.EqualTo("London"));
77+
Assert.That(londonParameter.Item2, Is.EqualTo(NHibernateUtil.StringClob));
78+
79+
var newYorkParameter = nhNewYork.ParameterValuesByName.Single().Value;
80+
Assert.That(newYorkParameter.Item1, Is.EqualTo("New York"));
81+
Assert.That(newYorkParameter.Item2, Is.EqualTo(NHibernateUtil.AnsiString));
82+
}
83+
}
84+
5885
[Test]
5986
public void Different_Where_Clauses_Return_Different_Keys()
6087
{

src/NHibernate/Linq/LinqExtensionMethods.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Linq;
44
using System.Linq.Expressions;
55
using NHibernate.Impl;
6+
using NHibernate.Type;
67
using Remotion.Linq;
78
using Remotion.Linq.Parsing.ExpressionTreeVisitors;
89

@@ -47,7 +48,6 @@ public static IQueryable<T> CacheRegion<T>(this IQueryable<T> query, string regi
4748
return new NhQueryable<T>(query.Provider, callExpression);
4849
}
4950

50-
5151
public static IQueryable<T> Timeout<T>(this IQueryable<T> query, int timeout)
5252
{
5353
var method = ReflectionHelper.GetMethodDefinition(() => Timeout<object>(null, 0)).MakeGenericMethod(typeof(T));
@@ -84,6 +84,11 @@ public static IFutureValue<T> ToFutureValue<T>(this IQueryable<T> query)
8484
return (IFutureValue<T>) future;
8585
}
8686

87+
public static T MappedAs<T>(this T parameter, IType type)
88+
{
89+
throw new InvalidOperationException("The method should be used inside Linq to indicate a type of a parameter");
90+
}
91+
8792
public static IFutureValue<TResult> ToFutureValue<T, TResult>(this IQueryable<T> query, Expression<Func<IQueryable<T>, TResult>> selector)
8893
{
8994
var nhQueryable = query as QueryableBase<T>;

src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Collections.ObjectModel;
43
using System.Linq;
54
using System.Linq.Expressions;
65
using System.Reflection;
76
using NHibernate.Engine;
87
using NHibernate.Param;
98
using NHibernate.Type;
109
using Remotion.Linq.Parsing;
11-
using Remotion.Linq.Utilities;
1210

1311
namespace NHibernate.Linq.Visitors
1412
{
@@ -44,6 +42,16 @@ public static IDictionary<ConstantExpression, NamedParameter> Visit(Expression e
4442

4543
protected override Expression VisitMethodCallExpression(MethodCallExpression expression)
4644
{
45+
if (expression.Method.Name == "MappedAs" && expression.Method.DeclaringType == typeof(LinqExtensionMethods))
46+
{
47+
var parameter = (ConstantExpression) VisitExpression(expression.Arguments[0]);
48+
var type = (ConstantExpression) expression.Arguments[1];
49+
50+
_parameters[parameter].Type = (IType) type.Value;
51+
52+
return parameter;
53+
}
54+
4755
var method = expression.Method.IsGenericMethod
4856
? expression.Method.GetGenericMethodDefinition()
4957
: expression.Method;

src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionTreeVisitor.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
using System.Linq.Expressions;
2+
using Remotion.Linq.Clauses.Expressions;
23
using Remotion.Linq.Parsing;
34
using Remotion.Linq.Parsing.ExpressionTreeVisitors;
45

56
namespace NHibernate.Linq.Visitors
67
{
7-
internal class NhPartialEvaluatingExpressionTreeVisitor : ExpressionTreeVisitor
8+
internal class NhPartialEvaluatingExpressionTreeVisitor : ExpressionTreeVisitor, IPartialEvaluationExceptionExpressionVisitor
89
{
910
protected override Expression VisitConstantExpression(ConstantExpression expression)
1011
{
@@ -22,5 +23,10 @@ public static Expression EvaluateIndependentSubtrees(Expression expression)
2223
var evaluatedExpression = PartialEvaluatingExpressionTreeVisitor.EvaluateIndependentSubtrees(expression);
2324
return new NhPartialEvaluatingExpressionTreeVisitor().VisitExpression(evaluatedExpression);
2425
}
26+
27+
public Expression VisitPartialEvaluationExceptionExpression(PartialEvaluationExceptionExpression expression)
28+
{
29+
return VisitExpression(expression.Reduce());
30+
}
2531
}
2632
}

0 commit comments

Comments
 (0)