|
From: <ric...@us...> - 2011-05-22 16:34:18
|
Revision: 5855
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5855&view=rev
Author: ricbrown
Date: 2011-05-22 16:34:11 +0000 (Sun, 22 May 2011)
Log Message:
-----------
NH-2683: Updated QueryOver Concat() extension to allow arbitrary parameters
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs
trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2011-05-22 14:58:58 UTC (rev 5854)
+++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2011-05-22 16:34:11 UTC (rev 5855)
@@ -451,5 +451,25 @@
{
return Projections.Sum(ExpressionProcessor.FindMemberExpression(expression.Body));
}
+
+ /// <summary>
+ /// Project SQL function concat()
+ /// Note: throws an exception outside of a QueryOver expression
+ /// </summary>
+ public static string Concat(params string[] strings)
+ {
+ throw new Exception("Not to be used directly - use inside QueryOver expression");
+ }
+
+ internal static IProjection ProcessConcat(MethodCallExpression methodCallExpression)
+ {
+ NewArrayExpression args = (NewArrayExpression)methodCallExpression.Arguments[0];
+ IProjection[] projections = new IProjection[args.Expressions.Count];
+
+ for (var i=0; i<args.Expressions.Count; i++)
+ projections[i] = ExpressionProcessor.FindMemberProjection(args.Expressions[i]);
+
+ return Projections.SqlFunction("concat", NHibernateUtil.String, projections);
+ }
}
}
Modified: trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 14:58:58 UTC (rev 5854)
+++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2011-05-22 16:34:11 UTC (rev 5855)
@@ -341,22 +341,6 @@
}
/// <summary>
- /// Project SQL function concat()
- /// Note: throws an exception outside of a QueryOver expression
- /// </summary>
- public static string ConcatStr(this string stringProperty, string value)
- {
- throw new Exception("Not to be used directly - use inside QueryOver expression");
- }
-
- internal static IProjection ProcessConcatStr(MethodCallExpression methodCallExpression)
- {
- IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]);
- object concatWithValue = ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]);
- return Projections.SqlFunction("concat", NHibernateUtil.String, property, Projections.Constant(string.Empty), Projections.Constant(concatWithValue));
- }
-
- /// <summary>
/// Project SQL function mod()
/// Note: throws an exception outside of a QueryOver expression
/// </summary>
Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 14:58:58 UTC (rev 5854)
+++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2011-05-22 16:34:11 UTC (rev 5855)
@@ -109,7 +109,7 @@
RegisterCustomProjection(() => ProjectionsExtensions.CharIndex(string.Empty, string.Empty, 0), ProjectionsExtensions.ProcessCharIndex);
RegisterCustomProjection(() => ProjectionsExtensions.Coalesce<DBNull>(null, null), ProjectionsExtensions.ProcessCoalesce);
RegisterCustomProjection(() => ProjectionsExtensions.Coalesce<int>(null, 0), ProjectionsExtensions.ProcessCoalesce);
- RegisterCustomProjection(() => ProjectionsExtensions.ConcatStr(string.Empty, string.Empty), ProjectionsExtensions.ProcessConcatStr);
+ RegisterCustomProjection(() => Projections.Concat(null), Projections.ProcessConcat);
RegisterCustomProjection(() => ProjectionsExtensions.Mod(0, 0), ProjectionsExtensions.ProcessMod);
RegisterCustomProjection(() => ProjectionsExtensions.Abs(default(int)), ProjectionsExtensions.ProcessIntAbs);
RegisterCustomProjection(() => ProjectionsExtensions.Abs(default(double)), ProjectionsExtensions.ProcessDoubleAbs);
@@ -163,6 +163,9 @@
/// </summary>
public static IProjection FindMemberProjection(Expression expression)
{
+ if (!IsMemberExpression(expression))
+ return Projections.Constant(FindValue(expression));
+
if (expression is UnaryExpression)
{
UnaryExpression unaryExpression = (UnaryExpression)expression;
@@ -309,6 +312,9 @@
private static bool IsMemberExpression(Expression expression)
{
+ if (expression is ParameterExpression)
+ return true;
+
if (expression is MemberExpression)
{
MemberExpression memberExpression = (MemberExpression)expression;
@@ -319,6 +325,13 @@
if (memberExpression.Expression.NodeType == ExpressionType.Parameter)
return true;
+ if (IsNullableOfT(memberExpression.Member.DeclaringType))
+ {
+ // it's a Nullable<T>, so ignore any .Value
+ if (memberExpression.Member.Name == "Value")
+ return IsMemberExpression(memberExpression.Expression);
+ }
+
if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess)
{
// if the member has a null value, it was an alias
@@ -337,6 +350,25 @@
return IsMemberExpression(unaryExpression.Operand);
}
+ if (expression is MethodCallExpression)
+ {
+ MethodCallExpression methodCallExpression = (MethodCallExpression)expression;
+
+ string signature = Signature(methodCallExpression.Method);
+ if (_customProjectionProcessors.ContainsKey(signature))
+ return true;
+
+ if (methodCallExpression.Method.Name == "GetType"
+ || methodCallExpression.Method.Name == "get_Item"
+ || methodCallExpression.Method.Name == "First")
+ {
+ if (IsMemberExpression(methodCallExpression.Object))
+ return true;
+
+ return EvaluatesToNull(methodCallExpression.Object);
+ }
+ }
+
return false;
}
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 14:58:58 UTC (rev 5854)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2011-05-22 16:34:11 UTC (rev 5855)
@@ -575,7 +575,7 @@
{
s.Save(new Person() { Name = "p1", BirthDate = new DateTime(2009, 08, 07), Age = 90 });
s.Save(new Person() { Name = "p2", BirthDate = new DateTime(2008, 07, 06) });
- s.Save(new Person() { Name = "p3", BirthDate = new DateTime(2007, 06, 05) });
+ s.Save(new Person() { Name = "pP3", BirthDate = new DateTime(2007, 06, 05) });
t.Commit();
}
@@ -614,6 +614,29 @@
sqrtOfAge.GetType().Should().Be(typeof(double));
string.Format("{0:0.00}", sqrtOfAge).Should().Be("9.49");
}
+
+ using (ISession s = OpenSession())
+ {
+ var names =
+ s.QueryOver<Person>()
+ .Where(p => p.Name == "pP3")
+ .Select(p => p.Name.Lower(), p => p.Name.Upper())
+ .SingleOrDefault<object[]>();
+
+ names[0].Should().Be("pp3");
+ names[1].Should().Be("PP3");
+ }
+
+ using (ISession s = OpenSession())
+ {
+ var name =
+ s.QueryOver<Person>()
+ .Where(p => p.Name == "p1")
+ .Select(p => Projections.Concat(p.Name, ", ", p.Name))
+ .SingleOrDefault<string>();
+
+ name.Should().Be("p1, p1");
+ }
}
[Test]
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 14:58:58 UTC (rev 5854)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2011-05-22 16:34:11 UTC (rev 5855)
@@ -277,7 +277,7 @@
.Add(Restrictions.Eq(Projections.SqlFunction("locate", NHibernateUtil.String, Projections.Constant("e"), Projections.Property("Name"), Projections.Constant(1)), 2))
.Add(Restrictions.Eq(Projections.SqlFunction("coalesce", NHibernateUtil.Object, Projections.Property("Name"), Projections.Constant("not-null-val")), "test"))
.Add(Restrictions.Eq(Projections.SqlFunction("coalesce", NHibernateUtil.Object, Projections.Property("NullableIsParent"), Projections.Constant(true)), true))
- .Add(Restrictions.Eq(Projections.SqlFunction("concat", NHibernateUtil.String, Projections.Property("Name"), Projections.Constant(string.Empty), Projections.Constant("A")), "testA"))
+ .Add(Restrictions.Eq(Projections.SqlFunction("concat", NHibernateUtil.String, Projections.Property("Name"), Projections.Constant(", "), Projections.Property("Name")), "test, test"))
.Add(Restrictions.Eq(Projections.SqlFunction("mod", NHibernateUtil.Int32, Projections.Property("Height"), Projections.Constant(10)), 0));
IQueryOver<Person> actual =
@@ -299,7 +299,7 @@
.And(p => p.Name.CharIndex("e", 1) == 2)
.And(p => p.Name.Coalesce("not-null-val") == "test")
.And(p => p.NullableIsParent.Coalesce(true) == true)
- .And(p => p.Name.ConcatStr("A") == "testA")
+ .And(p => Projections.Concat(p.Name, ", ", p.Name) == "test, test")
.And(p => p.Height.Mod(10) == 0);
AssertCriteriaAreEqual(expected, actual);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|