|
From: <ste...@us...> - 2009-11-05 16:43:54
|
Revision: 4819
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4819&view=rev
Author: steverstrong
Date: 2009-11-05 16:43:43 +0000 (Thu, 05 Nov 2009)
Log Message:
-----------
Further Linq updates, plus a change to the Cast dialect function
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs
trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/GroupByKeySelectorVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Shipper.cs
trunk/nhibernate/src/NHibernate.Test/Linq/LinqQuerySamples.cs
trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/Shipper.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Linq/Expressions/
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAggregatedExpression.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhDistinctExpression.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhExpressionType.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhMaxExpression.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhMinExpression.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhNewExpression.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhSumExpression.cs
trunk/nhibernate/src/NHibernate/Linq/GroupBy/
trunk/nhibernate/src/NHibernate/Linq/GroupBy/AggregatingGroupByRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/GroupBy/GroupByAggregateDetectionVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/GroupBy/GroupBySelectClauseRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/GroupBy/NonAggregatingGroupByRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/GroupJoin/
trunk/nhibernate/src/NHibernate/Linq/GroupJoin/AggregatingGroupJoinRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/GroupJoin/GroupJoinAggregateDetectionVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/GroupJoin/GroupJoinSelectClauseRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/GroupJoin/IsAggregatingResults.cs
trunk/nhibernate/src/NHibernate/Linq/GroupJoin/LocateGroupJoinQuerySource.cs
trunk/nhibernate/src/NHibernate/Linq/GroupJoin/NonAggregatingGroupJoinRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/ReWriters/QueryReferenceExpressionFlattener.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/EqualityHqlGenerator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/SwapQuerySourceVisitor.cs
trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs
trunk/nhibernate/src/NHibernate.Test/Linq/ObjectDumper.cs
Removed Paths:
-------------
trunk/nhibernate/src/NHibernate/Linq/NhNewExpression.cs
trunk/nhibernate/src/NHibernate/Linq/ReWriters/AggregatingGroupByRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/ReWriters/AggregatingGroupJoinRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/ReWriters/GroupBySelectClauseRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/ReWriters/NonAggregatingGroupByRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/GroupByAggregateDetectionVisitor.cs
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs 2009-11-04 10:55:10 UTC (rev 4818)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -15,16 +15,17 @@
[Serializable]
public class CastFunction : ISQLFunction, IFunctionGrammar
{
- private LazyType returnType;
+ //private LazyType returnType;
#region ISQLFunction Members
public IType ReturnType(IType columnType, IMapping mapping)
{
//note there is a weird implementation in the client side
//TODO: cast that use only costant are not supported in SELECT. Ex: cast(5 as string)
- return SetLazyType(columnType);
+ //return SetLazyType(columnType);
+ return columnType;
}
-
+ /*
private LazyType SetLazyType(IType columnType)
{
if(returnType == null)
@@ -34,6 +35,7 @@
returnType.RealType = columnType;
return returnType;
}
+ */
public bool HasArguments
{
get { return true; }
@@ -53,7 +55,7 @@
string typeName = args[1].ToString();
string sqlType;
IType hqlType = TypeFactory.HeuristicType(typeName);
- SetLazyType(hqlType);
+ //SetLazyType(hqlType);
if (hqlType != null)
{
SqlType[] sqlTypeCodes = hqlType.SqlTypes(factory);
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-04 10:55:10 UTC (rev 4818)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -133,6 +133,11 @@
_node.Text = "string";
break;
default:
+ if (type == typeof(Guid))
+ {
+ _node.Text = "guid";
+ break;
+ }
throw new NotSupportedException(string.Format("Don't currently support idents of type {0}", type.Name));
}
}
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAggregatedExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAggregatedExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAggregatedExpression.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,21 @@
+using System.Linq.Expressions;
+
+namespace NHibernate.Linq.Expressions
+{
+ public class NhAggregatedExpression : Expression
+ {
+ public Expression Expression { get; set; }
+
+ public NhAggregatedExpression(Expression expression, NhExpressionType type)
+ : base((ExpressionType)type, expression.Type)
+ {
+ Expression = expression;
+ }
+
+ public NhAggregatedExpression(Expression expression, System.Type expressionType, NhExpressionType type)
+ : base((ExpressionType)type, expressionType)
+ {
+ Expression = expression;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,11 @@
+using System.Linq.Expressions;
+
+namespace NHibernate.Linq.Expressions
+{
+ public class NhAverageExpression : NhAggregatedExpression
+ {
+ public NhAverageExpression(Expression expression) : base(expression, NhExpressionType.Average)
+ {
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,12 @@
+using System.Linq.Expressions;
+
+namespace NHibernate.Linq.Expressions
+{
+ public class NhCountExpression : NhAggregatedExpression
+ {
+ public NhCountExpression(Expression expression)
+ : base(expression, typeof(int), NhExpressionType.Count)
+ {
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhDistinctExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhDistinctExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhDistinctExpression.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,12 @@
+using System.Linq.Expressions;
+
+namespace NHibernate.Linq.Expressions
+{
+ public class NhDistinctExpression : NhAggregatedExpression
+ {
+ public NhDistinctExpression(Expression expression)
+ : base(expression, NhExpressionType.Distinct)
+ {
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhExpressionType.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhExpressionType.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhExpressionType.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,13 @@
+namespace NHibernate.Linq.Expressions
+{
+ public enum NhExpressionType
+ {
+ Average = 10000,
+ Min,
+ Max,
+ Sum,
+ Count,
+ Distinct,
+ New
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhMaxExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhMaxExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhMaxExpression.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,12 @@
+using System.Linq.Expressions;
+
+namespace NHibernate.Linq.Expressions
+{
+ public class NhMaxExpression : NhAggregatedExpression
+ {
+ public NhMaxExpression(Expression expression)
+ : base(expression, NhExpressionType.Max)
+ {
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhMinExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhMinExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhMinExpression.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,12 @@
+using System.Linq.Expressions;
+
+namespace NHibernate.Linq.Expressions
+{
+ public class NhMinExpression : NhAggregatedExpression
+ {
+ public NhMinExpression(Expression expression)
+ : base(expression, NhExpressionType.Min)
+ {
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhNewExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhNewExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhNewExpression.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq.Expressions;
+
+namespace NHibernate.Linq.Expressions
+{
+ public class NhNewExpression : Expression
+ {
+ private readonly ReadOnlyCollection<string> _members;
+ private readonly ReadOnlyCollection<Expression> _arguments;
+
+ public NhNewExpression(IList<string> members, IList<Expression> arguments)
+ : base((ExpressionType)NhExpressionType.New, typeof(object))
+ {
+ _members = new ReadOnlyCollection<string>(members);
+ _arguments = new ReadOnlyCollection<Expression>(arguments);
+ }
+
+ public ReadOnlyCollection<Expression> Arguments
+ {
+ get { return _arguments; }
+ }
+
+ public ReadOnlyCollection<string> Members
+ {
+ get { return _members; }
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhSumExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhSumExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhSumExpression.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,12 @@
+using System.Linq.Expressions;
+
+namespace NHibernate.Linq.Expressions
+{
+ public class NhSumExpression : NhAggregatedExpression
+ {
+ public NhSumExpression(Expression expression)
+ : base(expression, NhExpressionType.Sum)
+ {
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/GroupBy/AggregatingGroupByRewriter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/GroupBy/AggregatingGroupByRewriter.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/GroupBy/AggregatingGroupByRewriter.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,88 @@
+using System;
+using System.Linq;
+using NHibernate.Linq.Visitors;
+using Remotion.Data.Linq;
+using Remotion.Data.Linq.Clauses;
+using Remotion.Data.Linq.Clauses.Expressions;
+using Remotion.Data.Linq.Clauses.ResultOperators;
+
+namespace NHibernate.Linq.GroupBy
+{
+ /// <summary>
+ /// An AggregatingGroupBy is a query such as:
+ ///
+ /// from p in db.Products
+ /// group p by p.Category.CategoryId
+ /// into g
+ /// select new
+ /// {
+ /// g.Key,
+ /// MaxPrice = g.Max(p => p.UnitPrice)
+ /// };
+ ///
+ /// Where the grouping operation is being fully aggregated and hence does not create any form of heirarchy.
+ /// This class takes such queries, flattens out the re-linq sub-query and re-writes the outer select
+ /// </summary>
+ public class AggregatingGroupByRewriter
+ {
+ private AggregatingGroupByRewriter()
+ {
+ }
+
+ public static void ReWrite(QueryModel queryModel)
+ {
+ var subQueryExpression = queryModel.MainFromClause.FromExpression as SubQueryExpression;
+
+ if ((subQueryExpression != null) &&
+ (subQueryExpression.QueryModel.ResultOperators.Count() == 1) &&
+ (subQueryExpression.QueryModel.ResultOperators[0] is GroupResultOperator) &&
+ (IsAggregatingGroupBy(queryModel)))
+ {
+ var rewriter = new AggregatingGroupByRewriter();
+ rewriter.FlattenSubQuery(subQueryExpression, queryModel.MainFromClause, queryModel);
+ }
+ }
+
+ private static bool IsAggregatingGroupBy(QueryModel queryModel)
+ {
+ return new GroupByAggregateDetectionVisitor().Visit(queryModel.SelectClause.Selector);
+ }
+
+ private void FlattenSubQuery(SubQueryExpression subQueryExpression, FromClauseBase fromClause,
+ QueryModel queryModel)
+ {
+ // Move the result operator up
+ if (queryModel.ResultOperators.Count != 0)
+ {
+ throw new NotImplementedException();
+ }
+
+ var groupBy = (GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0];
+
+ // Replace the outer select clause...
+ queryModel.SelectClause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel));
+
+ queryModel.SelectClause.TransformExpressions(
+ s =>
+ new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryExpression.QueryModel.MainFromClause).Swap
+ (s));
+
+ MainFromClause innerMainFromClause = subQueryExpression.QueryModel.MainFromClause;
+ CopyFromClauseData(innerMainFromClause, fromClause);
+
+ foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses)
+ {
+ queryModel.BodyClauses.Add(bodyClause);
+ }
+
+ queryModel.ResultOperators.Add(groupBy);
+ }
+
+ protected void CopyFromClauseData(FromClauseBase source, FromClauseBase destination)
+ {
+ destination.FromExpression = source.FromExpression;
+ destination.ItemName = source.ItemName;
+ destination.ItemType = source.ItemType;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/GroupBy/GroupByAggregateDetectionVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/GroupBy/GroupByAggregateDetectionVisitor.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/GroupBy/GroupByAggregateDetectionVisitor.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,61 @@
+using System.Linq;
+using System.Linq.Expressions;
+using NHibernate.Linq.Expressions;
+using NHibernate.Linq.Visitors;
+using Remotion.Data.Linq.Clauses.Expressions;
+
+namespace NHibernate.Linq.GroupBy
+{
+ // TODO: This needs strengthening. Possibly a lot in common with the GroupJoinAggregateDetectionVisitor class, which does many more checks
+ /// <summary>
+ /// Detects if an expression tree contains aggregate functions
+ /// </summary>
+ internal class GroupByAggregateDetectionVisitor : NhExpressionTreeVisitor
+ {
+ public bool ContainsAggregateMethods { get; private set; }
+
+ public bool Visit(Expression expression)
+ {
+ ContainsAggregateMethods = false;
+
+ VisitExpression(expression);
+
+ return ContainsAggregateMethods;
+ }
+
+ // TODO - this should not exist, since it should be handled either by re-linq or by the MergeAggregatingResultsRewriter
+ protected override Expression VisitMethodCallExpression(MethodCallExpression m)
+ {
+ if (m.Method.DeclaringType == typeof (Queryable) ||
+ m.Method.DeclaringType == typeof (Enumerable))
+ {
+ switch (m.Method.Name)
+ {
+ case "Count":
+ case "Min":
+ case "Max":
+ case "Sum":
+ case "Average":
+ ContainsAggregateMethods = true;
+ break;
+ }
+ }
+
+ return m;
+ }
+
+ protected override Expression VisitNhAggregate(NhAggregatedExpression expression)
+ {
+ ContainsAggregateMethods = true;
+ return expression;
+ }
+
+ protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
+ {
+ ContainsAggregateMethods =
+ new GroupByAggregateDetectionVisitor().Visit(expression.QueryModel.SelectClause.Selector);
+
+ return expression;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/GroupBy/GroupBySelectClauseRewriter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/GroupBy/GroupBySelectClauseRewriter.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/GroupBy/GroupBySelectClauseRewriter.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,131 @@
+using System;
+using System.Linq.Expressions;
+using NHibernate.Linq.Visitors;
+using Remotion.Data.Linq;
+using Remotion.Data.Linq.Clauses;
+using Remotion.Data.Linq.Clauses.Expressions;
+using Remotion.Data.Linq.Clauses.ResultOperators;
+
+namespace NHibernate.Linq.GroupBy
+{
+ internal class GroupBySelectClauseRewriter : NhExpressionTreeVisitor
+ {
+ public static Expression ReWrite(Expression expression, GroupResultOperator groupBy, QueryModel model)
+ {
+ var visitor = new GroupBySelectClauseRewriter(groupBy, model);
+ return visitor.VisitExpression(expression);
+ }
+
+ private readonly GroupResultOperator _groupBy;
+ private readonly QueryModel _model;
+
+ public GroupBySelectClauseRewriter(GroupResultOperator groupBy, QueryModel model)
+ {
+ _groupBy = groupBy;
+ _model = model;
+ }
+
+ protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
+ {
+ if (expression.ReferencedQuerySource == _groupBy)
+ {
+ return _groupBy.ElementSelector;
+ }
+
+ return base.VisitQuerySourceReferenceExpression(expression);
+ }
+
+ protected override Expression VisitMemberExpression(MemberExpression expression)
+ {
+ if (IsMemberOfModel(expression))
+ {
+ if (expression.Member.Name == "Key")
+ {
+ return _groupBy.KeySelector;
+ }
+ else
+ {
+ Expression elementSelector = _groupBy.ElementSelector;
+
+ if ((elementSelector is MemberExpression) || (elementSelector is QuerySourceReferenceExpression))
+ {
+ // If ElementSelector is MemberExpression, just return
+ return base.VisitMemberExpression(expression);
+ }
+ else if (elementSelector is NewExpression)
+ {
+ // If ElementSelector is NewExpression, then search for member of name "get_" + originalMemberExpression.Member.Name
+ // TODO - this wouldn't handle nested initialisers. Should do a tree walk to find the correct member
+ var nex = elementSelector as NewExpression;
+
+ int i = 0;
+ foreach (var member in nex.Members)
+ {
+ if (member.Name == "get_" + expression.Member.Name)
+ {
+ return nex.Arguments[i];
+ }
+ i++;
+ }
+
+ throw new NotImplementedException();
+ }
+ else
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+ else
+ {
+ return base.VisitMemberExpression(expression);
+ }
+ }
+
+ // TODO - dislike this code intensly. Should probably be a tree-walk in its own right
+ private bool IsMemberOfModel(MemberExpression expression)
+ {
+ var querySourceRef = expression.Expression as QuerySourceReferenceExpression;
+
+ if (querySourceRef == null)
+ {
+ return false;
+ }
+
+ var fromClause = querySourceRef.ReferencedQuerySource as FromClauseBase;
+
+ if (fromClause == null)
+ {
+ return false;
+ }
+
+ var subQuery = fromClause.FromExpression as SubQueryExpression;
+
+ if (subQuery != null)
+ {
+ return subQuery.QueryModel == _model;
+ }
+
+ var referencedQuery = fromClause.FromExpression as QuerySourceReferenceExpression;
+
+ if (referencedQuery == null)
+ {
+ return false;
+ }
+
+ var querySource = referencedQuery.ReferencedQuerySource as FromClauseBase;
+
+ var subQuery2 = querySource.FromExpression as SubQueryExpression;
+
+ return (subQuery2.QueryModel == _model);
+ }
+
+ protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
+ {
+ // TODO - is this safe? All we are extracting is the select clause from the sub-query. Assumes that everything
+ // else in the subquery has been removed. If there were two subqueries, one aggregating & one not, this may not be a
+ // valid assumption. Should probably be passed a list of aggregating subqueries that we are flattening so that we can check...
+ return GroupBySelectClauseRewriter.ReWrite(expression.QueryModel.SelectClause.Selector, _groupBy, _model);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/GroupBy/NonAggregatingGroupByRewriter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/GroupBy/NonAggregatingGroupByRewriter.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/GroupBy/NonAggregatingGroupByRewriter.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,108 @@
+using System;
+using System.Linq;
+using System.Linq.Expressions;
+using NHibernate.Linq.ResultOperators;
+using NHibernate.Linq.Visitors;
+using Remotion.Data.Linq;
+using Remotion.Data.Linq.Clauses;
+using Remotion.Data.Linq.Clauses.Expressions;
+using Remotion.Data.Linq.Clauses.ResultOperators;
+
+namespace NHibernate.Linq.GroupBy
+{
+ public class NonAggregatingGroupByRewriter
+ {
+ private NonAggregatingGroupByRewriter()
+ {
+ }
+
+ public static void ReWrite(QueryModel queryModel)
+ {
+ var subQueryExpression = queryModel.MainFromClause.FromExpression as SubQueryExpression;
+
+ if ((subQueryExpression != null) &&
+ (subQueryExpression.QueryModel.ResultOperators.Count() == 1) &&
+ (subQueryExpression.QueryModel.ResultOperators[0] is GroupResultOperator) &&
+ (IsNonAggregatingGroupBy(queryModel)))
+ {
+ var rewriter = new NonAggregatingGroupByRewriter();
+ rewriter.FlattenSubQuery(subQueryExpression, queryModel.MainFromClause, queryModel);
+ }
+ }
+
+ private void FlattenSubQuery(SubQueryExpression subQueryExpression, MainFromClause fromClause,
+ QueryModel queryModel)
+ {
+ // Create a new client-side select for the outer
+ // TODO - don't like calling GetGenericArguments here...
+ var clientSideSelect = new ClientSideSelect(new NonAggregatingGroupBySelectRewriter().Visit(queryModel.SelectClause.Selector, subQueryExpression.Type.GetGenericArguments()[0], queryModel.MainFromClause));
+
+ // Replace the outer select clause...
+ queryModel.SelectClause = subQueryExpression.QueryModel.SelectClause;
+
+ MainFromClause innerMainFromClause = subQueryExpression.QueryModel.MainFromClause;
+
+ CopyFromClauseData(innerMainFromClause, fromClause);
+
+ foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses)
+ {
+ queryModel.BodyClauses.Add(bodyClause);
+ }
+
+ // Move the result operator up
+ if (queryModel.ResultOperators.Count != 0)
+ {
+ throw new NotImplementedException();
+ }
+
+ queryModel.ResultOperators.Add(new NonAggregatingGroupBy((GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0]));
+ queryModel.ResultOperators.Add(clientSideSelect);
+ }
+
+ protected void CopyFromClauseData(FromClauseBase source, FromClauseBase destination)
+ {
+ destination.FromExpression = source.FromExpression;
+ destination.ItemName = source.ItemName;
+ destination.ItemType = source.ItemType;
+ }
+
+ private static bool IsNonAggregatingGroupBy(QueryModel queryModel)
+ {
+ return new GroupByAggregateDetectionVisitor().Visit(queryModel.SelectClause.Selector) == false;
+ }
+ }
+
+ internal class NonAggregatingGroupBySelectRewriter : NhExpressionTreeVisitor
+ {
+ private ParameterExpression _inputParameter;
+ private IQuerySource _querySource;
+
+ public LambdaExpression Visit(Expression clause, System.Type resultType, IQuerySource querySource)
+ {
+ _inputParameter = Expression.Parameter(resultType, "inputParameter");
+ _querySource = querySource;
+
+ return Expression.Lambda(VisitExpression(clause), _inputParameter);
+ }
+
+ protected override Expression VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
+ {
+ if (expression.ReferencedQuerySource == _querySource)
+ {
+ return _inputParameter;
+ }
+
+ return expression;
+ }
+ }
+
+ internal class ClientSideSelect : ClientSideTransformOperator
+ {
+ public LambdaExpression SelectClause { get; private set; }
+
+ public ClientSideSelect(LambdaExpression selectClause)
+ {
+ SelectClause = selectClause;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/GroupJoin/AggregatingGroupJoinRewriter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/GroupJoin/AggregatingGroupJoinRewriter.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/GroupJoin/AggregatingGroupJoinRewriter.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,66 @@
+using System.Collections.Generic;
+using System.Linq;
+using Remotion.Data.Linq;
+using Remotion.Data.Linq.Clauses;
+
+namespace NHibernate.Linq.GroupJoin
+{
+ /// <summary>
+ /// An AggregatingGroupJoin is a query such as:
+ ///
+ /// from c in db.Customers
+ /// join o in db.Orders on c.CustomerId equals o.Customer.CustomerId into ords
+ /// join e in db.Employees on c.Address.City equals e.Address.City into emps
+ /// select new { c.ContactName, ords = ords.Count(), emps = emps.Count() };
+ ///
+ /// where the results of the joins are being fully aggregated and hence do not create any form of hierarchy.
+ /// This class takes such expressions and turns them into this form:
+ ///
+ /// from c in db.Customers
+ /// select new
+ /// {
+ /// c.ContactName,
+ /// ords = (from o2 in db.Orders where o2.Customer.CustomerId == c.CustomerId select o2).Count(),
+ /// emps = (from e2 in db.Employees where e2.Address.City == c.Address.City select e2).Count()
+ /// };
+ ///
+ /// </summary>
+ public class AggregatingGroupJoinRewriter
+ {
+ private AggregatingGroupJoinRewriter()
+ {
+ }
+
+ public static void ReWrite(QueryModel model)
+ {
+ // firstly, get the group join clauses
+ var groupJoin = model.BodyClauses.Where(bc => bc is GroupJoinClause).Cast<GroupJoinClause>();
+
+ if (groupJoin.Count() == 0)
+ {
+ // No group join here..
+ return;
+ }
+
+ // Now walk the tree to decide which groupings are fully aggregated (and can hence be done in hql)
+ var aggregateDetectorResults = IsAggregatingGroupJoin(model, groupJoin);
+
+ if (aggregateDetectorResults.AggregatingClauses.Count > 0)
+ {
+ // Re-write the select expression
+ model.SelectClause.TransformExpressions(s => GroupJoinSelectClauseRewriter.ReWrite(s, aggregateDetectorResults));
+
+ // Remove the aggregating group joins
+ foreach (GroupJoinClause aggregatingGroupJoin in aggregateDetectorResults.AggregatingClauses)
+ {
+ model.BodyClauses.Remove(aggregatingGroupJoin);
+ }
+ }
+ }
+
+ private static IsAggregatingResults IsAggregatingGroupJoin(QueryModel model, IEnumerable<GroupJoinClause> clause)
+ {
+ return GroupJoinAggregateDetectionVisitor.Visit(clause, model.SelectClause.Selector);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/GroupJoin/GroupJoinAggregateDetectionVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/GroupJoin/GroupJoinAggregateDetectionVisitor.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/GroupJoin/GroupJoinAggregateDetectionVisitor.cs 2009-11-05 16:43:43 UTC (rev 4819)
@@ -0,0 +1,116 @@
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using NHibernate.Linq.Expressions;
+using NHibernate.Linq.Visitors;
+using Remotion.Data.Linq.Clauses;
+using Remotion.Data.Linq.Clauses.Expressions;
+
+namespace NHibernate.Linq.GroupJoin
+{
+ internal class GroupJoinAggregateDetectionVisitor : NhExpressionTreeVisitor
+ {
+ private readonly HashSet<GroupJoinClau...
[truncated message content] |
|
From: <ste...@us...> - 2009-11-05 17:19:32
|
Revision: 4820
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4820&view=rev
Author: steverstrong
Date: 2009-11-05 17:19:23 +0000 (Thu, 05 Nov 2009)
Log Message:
-----------
Removed some unused code
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs
trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs 2009-11-05 16:43:43 UTC (rev 4819)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs 2009-11-05 17:19:23 UTC (rev 4820)
@@ -15,27 +15,15 @@
[Serializable]
public class CastFunction : ISQLFunction, IFunctionGrammar
{
- //private LazyType returnType;
#region ISQLFunction Members
public IType ReturnType(IType columnType, IMapping mapping)
{
//note there is a weird implementation in the client side
//TODO: cast that use only costant are not supported in SELECT. Ex: cast(5 as string)
- //return SetLazyType(columnType);
return columnType;
}
- /*
- private LazyType SetLazyType(IType columnType)
- {
- if(returnType == null)
- {
- returnType = new LazyType();
- }
- returnType.RealType = columnType;
- return returnType;
- }
- */
+
public bool HasArguments
{
get { return true; }
@@ -55,7 +43,7 @@
string typeName = args[1].ToString();
string sqlType;
IType hqlType = TypeFactory.HeuristicType(typeName);
- //SetLazyType(hqlType);
+
if (hqlType != null)
{
SqlType[] sqlTypeCodes = hqlType.SqlTypes(factory);
@@ -107,217 +95,5 @@
}
#endregion
-
- /// <summary>
- /// Delegate the values to a real type
- /// </summary>
- /// <remarks>
- /// The real return type of Cast is know only after the Cast is parsed.
- /// This class was created in NH to remove the responsibility of the parser about know the
- /// real return type.
- /// </remarks>
- [Serializable]
- private class LazyType: IType
- {
- public IType RealType { get; set; }
-
- #region Implementation of ICacheAssembler
-
- public object Disassemble(object value, ISessionImplementor session, object owner)
- {
- return RealType.Disassemble(value, session, owner);
- }
-
- public object Assemble(object cached, ISessionImplementor session, object owner)
- {
- return RealType.Assemble(cached, session, owner);
- }
-
- public void BeforeAssemble(object cached, ISessionImplementor session)
- {
- RealType.BeforeAssemble(cached, session);
- }
-
- #endregion
-
- #region Implementation of IType
-
- public string Name
- {
- get { return RealType.Name; }
- }
-
- public System.Type ReturnedClass
- {
- get { return RealType.ReturnedClass; }
- }
-
- public bool IsMutable
- {
- get { return RealType.IsMutable; }
- }
-
- public bool IsAssociationType
- {
- get { return RealType.IsAssociationType; }
- }
-
- public bool IsXMLElement
- {
- get { return RealType.IsXMLElement; }
- }
-
- public bool IsCollectionType
- {
- get { return RealType.IsCollectionType; }
- }
-
- public bool IsComponentType
- {
- get { return RealType.IsComponentType; }
- }
-
- public bool IsEntityType
- {
- get { return RealType.IsEntityType; }
- }
-
- public bool IsAnyType
- {
- get { return RealType.IsAnyType; }
- }
-
- public SqlType[] SqlTypes(IMapping mapping)
- {
- return RealType.SqlTypes(mapping);
- }
-
- public int GetColumnSpan(IMapping mapping)
- {
- return RealType.GetColumnSpan(mapping);
- }
-
- public bool IsDirty(object old, object current, ISessionImplementor session)
- {
- return RealType.IsDirty(old, current, session);
- }
-
- public bool IsDirty(object old, object current, bool[] checkable, ISessionImplementor session)
- {
- return RealType.IsDirty(old, current, checkable, session);
- }
-
- public bool IsModified(object oldHydratedState, object currentState, bool[] checkable, ISessionImplementor session)
- {
- return RealType.IsModified(oldHydratedState, currentState, checkable, session);
- }
-
- public object NullSafeGet(IDataReader rs, string[] names, ISessionImplementor session, object owner)
- {
- return RealType.NullSafeGet(rs, names, session, owner);
- }
-
- public object NullSafeGet(IDataReader rs, string name, ISessionImplementor session, object owner)
- {
- return RealType.NullSafeGet(rs, name, session, owner);
- }
-
- public void NullSafeSet(IDbCommand st, object value, int index, bool[] settable, ISessionImplementor session)
- {
- RealType.NullSafeSet(st, value, index, settable, session);
- }
-
- public void NullSafeSet(IDbCommand st, object value, int index, ISessionImplementor session)
- {
- RealType.NullSafeSet(st, value, index, session);
- }
-
- public string ToLoggableString(object value, ISessionFactoryImplementor factory)
- {
- return RealType.ToLoggableString(value, factory);
- }
-
- public object DeepCopy(object val, EntityMode entityMode, ISessionFactoryImplementor factory)
- {
- return RealType.DeepCopy(val, entityMode, factory);
- }
-
- public object Hydrate(IDataReader rs, string[] names, ISessionImplementor session, object owner)
- {
- return RealType.Hydrate(rs, names, session, owner);
- }
-
- public object ResolveIdentifier(object value, ISessionImplementor session, object owner)
- {
- return RealType.ResolveIdentifier(value, session, owner);
- }
-
- public object SemiResolve(object value, ISessionImplementor session, object owner)
- {
- return RealType.SemiResolve(value, session, owner);
- }
-
- public object Replace(object original, object target, ISessionImplementor session, object owner, IDictionary copiedAlready)
- {
- return RealType.Replace(original, target, session, owner, copiedAlready);
- }
-
- public object Replace(object original, object target, ISessionImplementor session, object owner, IDictionary copyCache, ForeignKeyDirection foreignKeyDirection)
- {
- return RealType.Replace(original, target, session, owner, copyCache, foreignKeyDirection);
- }
-
- public bool IsSame(object x, object y, EntityMode entityMode)
- {
- return RealType.IsSame(x, y, entityMode);
- }
-
- public bool IsEqual(object x, object y, EntityMode entityMode)
- {
- return RealType.IsEqual(x, y, entityMode);
- }
-
- public bool IsEqual(object x, object y, EntityMode entityMode, ISessionFactoryImplementor factory)
- {
- return RealType.IsEqual(x, y, entityMode, factory);
- }
-
- public int GetHashCode(object x, EntityMode entityMode)
- {
- return RealType.GetHashCode(x, entityMode);
- }
-
- public int GetHashCode(object x, EntityMode entityMode, ISessionFactoryImplementor factory)
- {
- return RealType.GetHashCode(x, entityMode, factory);
- }
-
- public int Compare(object x, object y, EntityMode? entityMode)
- {
- return RealType.Compare(x, y, entityMode);
- }
-
- public IType GetSemiResolvedType(ISessionFactoryImplementor factory)
- {
- return RealType.GetSemiResolvedType(factory);
- }
-
- public void SetToXMLNode(XmlNode node, object value, ISessionFactoryImplementor factory)
- {
- RealType.SetToXMLNode(node, value, factory);
- }
-
- public object FromXMLNode(XmlNode xml, IMapping factory)
- {
- return RealType.FromXMLNode(xml, factory);
- }
-
- public bool[] ToColumnNullness(object value, IMapping mapping)
- {
- return RealType.ToColumnNullness(value, mapping);
- }
-
- #endregion
- }
}
}
Modified: trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs 2009-11-05 16:43:43 UTC (rev 4819)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/MiscellaneousTextFixture.cs 2009-11-05 17:19:23 UTC (rev 4820)
@@ -23,13 +23,6 @@
[Test(Description = "This sample uses Count to find the number of Orders placed before yesterday in the database.")]
public void CountWithWhereClause()
{
- using (var s = OpenSession())
- {
- var r = s.CreateQuery("select cast(count(o), int) from Order o where o.OrderDate <= cast(:p1, datetime)")
- .SetParameter("p1", DateTime.Today.AddDays(-1))
- .List();
- }
-
var q = from o in db.Orders where o.OrderDate <= DateTime.Today.AddDays(-1) select o;
int count = q.Count();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-05 17:46:42
|
Revision: 4821
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4821&view=rev
Author: ricbrown
Date: 2009-11-05 17:46:33 +0000 (Thu, 05 Nov 2009)
Log Message:
-----------
Initial stab at sub-query syntax for QueryOver.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/DetachedCriteria.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate/IQueryOver.cs
trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/LambdaFixtureBase.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/DetachedCriteria.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/DetachedCriteria.cs 2009-11-05 17:19:23 UTC (rev 4820)
+++ trunk/nhibernate/src/NHibernate/Criterion/DetachedCriteria.cs 2009-11-05 17:46:33 UTC (rev 4821)
@@ -45,7 +45,7 @@
criteria = impl;
}
- protected DetachedCriteria(CriteriaImpl impl, ICriteria criteria)
+ protected internal DetachedCriteria(CriteriaImpl impl, ICriteria criteria)
{
this.impl = impl;
this.criteria = criteria;
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-05 17:19:23 UTC (rev 4820)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-05 17:46:33 UTC (rev 4821)
@@ -9,16 +9,34 @@
namespace NHibernate.Criterion
{
+ [Serializable]
+ public class QueryOver
+ {
+
+ protected ICriteria _criteria;
+ protected CriteriaImpl _impl;
+
+ protected QueryOver() { }
+
+ public ICriteria UnderlyingCriteria
+ {
+ get { return _criteria; }
+ }
+
+ public DetachedCriteria DetachedCriteria
+ {
+ get { return new DetachedCriteria(_impl, _impl); }
+ }
+
+ }
+
/// <summary>
/// Implementation of the <see cref="IQueryOver<T>"/> interface
/// </summary>
[Serializable]
- public class QueryOver<T> : IQueryOver<T>
+ public class QueryOver<T> : QueryOver, IQueryOver<T>
{
- private ICriteria _criteria;
- private CriteriaImpl _impl;
-
public QueryOver()
{
_impl = new CriteriaImpl(typeof(T), null);
@@ -44,9 +62,15 @@
_criteria = criteria;
}
- public ICriteria UnderlyingCriteria
+ /// <summary>
+ /// Method to allow comparison of detached query in Lambda expression
+ /// e.g., p => p.Name == myQuery.As<string>
+ /// </summary>
+ /// <typeparam name="T">type returned by query</typeparam>
+ /// <returns>throws an exception if evaluated directly at runtime.</returns>
+ public R As<R>()
{
- get { return _criteria; }
+ throw new HibernateException("Incorrect syntax; .As<T> method is for use in Lambda expressions only.");
}
public QueryOver<T> And(Expression<Func<T, bool>> expression)
@@ -146,6 +170,11 @@
return this;
}
+ QueryOverSubqueryBuilder<T> WithSubquery
+ {
+ get { return new QueryOverSubqueryBuilder<T>(this); }
+ }
+
public QueryOverFetchBuilder<T> Fetch(Expression<Func<T, object>> path)
{
return new QueryOverFetchBuilder<T>(this, path);
@@ -469,6 +498,9 @@
IQueryOver<T> IQueryOver<T>.CacheRegion(string cacheRegion)
{ return CacheRegion(cacheRegion); }
+ IQueryOverSubqueryBuilder<T> IQueryOver<T>.WithSubquery
+ { get { return new IQueryOverSubqueryBuilder<T>(this); } }
+
IQueryOverFetchBuilder<T> IQueryOver<T>.Fetch(Expression<Func<T, object>> path)
{ return new IQueryOverFetchBuilder<T>(this, path); }
Added: trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs 2009-11-05 17:46:33 UTC (rev 4821)
@@ -0,0 +1,59 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion
+{
+
+ public class QueryOverSubqueryBuilder<T> : QueryOverSubqueryBuilderBase<QueryOver<T>, T, QueryOverSubqueryPropertyBuilder<T>>
+ {
+
+ public QueryOverSubqueryBuilder(QueryOver<T> root)
+ : base(root) { }
+
+ }
+
+ public class IQueryOverSubqueryBuilder<T> : QueryOverSubqueryBuilderBase<IQueryOver<T>, T, IQueryOverSubqueryPropertyBuilder<T>>
+ {
+
+ public IQueryOverSubqueryBuilder(IQueryOver<T> root)
+ : base(root) { }
+
+ }
+
+ public class QueryOverSubqueryBuilderBase<R, T, S>
+ where R : IQueryOver<T>
+ where S : QueryOverSubqueryPropertyBuilderBase, new()
+ {
+
+ protected R root;
+
+ protected QueryOverSubqueryBuilderBase(R root)
+ {
+ this.root = root;
+ }
+
+ /// <summary>
+ /// Subquery expression in the format
+ /// .Where(t => t.Property [==, !=, >, etc.] detachedQueryOver.As<propertyType>())
+ /// </summary>
+ public R Where(Expression<Func<T, bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery<T>(LambdaSubqueryType.Exact, expression);
+ root.And(criterion);
+ return root;
+ }
+
+ public S WhereProperty(Expression<Func<T, object>> expression)
+ {
+ string property = ExpressionProcessor.FindMemberExpression(expression.Body);
+ return (S) new S().Set(root, property);
+ }
+
+ }
+
+}
Added: trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs 2009-11-05 17:46:33 UTC (rev 4821)
@@ -0,0 +1,65 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion
+{
+
+ public class QueryOverSubqueryPropertyBuilder<T> : QueryOverSubqueryPropertyBuilderBase<QueryOver<T>, T>
+ {
+
+ public QueryOverSubqueryPropertyBuilder()
+ : base() { }
+
+ }
+
+ public class IQueryOverSubqueryPropertyBuilder<T> : QueryOverSubqueryPropertyBuilderBase<IQueryOver<T>, T>
+ {
+
+ public IQueryOverSubqueryPropertyBuilder()
+ : base() { }
+
+ }
+
+ public abstract class QueryOverSubqueryPropertyBuilderBase
+ {
+ protected QueryOverSubqueryPropertyBuilderBase() { }
+
+ public abstract QueryOverSubqueryPropertyBuilderBase Set(object root, string path);
+ }
+
+ public class QueryOverSubqueryPropertyBuilderBase<R, T> : QueryOverSubqueryPropertyBuilderBase
+ where R : IQueryOver<T>
+ {
+
+ protected R root;
+ protected string path;
+
+ protected QueryOverSubqueryPropertyBuilderBase()
+ {
+ }
+
+ public override QueryOverSubqueryPropertyBuilderBase Set(object root, string path)
+ {
+ this.root = (R)root;
+ this.path = path;
+ return this;
+ }
+
+ /// <summary>
+ /// Add a property equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Eq(QueryOver<T> detachedCriteria)
+ {
+ root.Where(Subqueries.PropertyEq(path, detachedCriteria.DetachedCriteria));
+ return root;
+ }
+
+ }
+
+}
Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-05 17:19:23 UTC (rev 4820)
+++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-05 17:46:33 UTC (rev 4821)
@@ -137,6 +137,11 @@
IQueryOver<T> CacheRegion(string cacheRegion);
/// <summary>
+ /// Add a subquery expression
+ /// </summary>
+ IQueryOverSubqueryBuilder<T> WithSubquery { get; }
+
+ /// <summary>
/// Specify an association fetching strategy. Currently, only
/// one-to-many and one-to-one associations are supported.
/// </summary>
Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2009-11-05 17:19:23 UTC (rev 4820)
+++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2009-11-05 17:46:33 UTC (rev 4821)
@@ -176,11 +176,11 @@
MethodCallExpression methodCallExpression = expression as MethodCallExpression;
if (methodCallExpression == null)
- throw new Exception("right operand should be detachedCriteriaInstance.As<T>() - " + expression.ToString());
+ throw new Exception("right operand should be detachedQueryInstance.As<T>() - " + expression.ToString());
- var criteriaExpression = Expression.Lambda(methodCallExpression.Arguments[0]).Compile();
- object detachedCriteria = criteriaExpression.DynamicInvoke();
- return (DetachedCriteria)detachedCriteria;
+ var criteriaExpression = Expression.Lambda(methodCallExpression.Object).Compile();
+ QueryOver detachedQuery = (QueryOver)criteriaExpression.DynamicInvoke();
+ return detachedQuery.DetachedCriteria;
}
private static bool EvaluatesToNull(Expression expression)
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-05 17:19:23 UTC (rev 4820)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-05 17:46:33 UTC (rev 4821)
@@ -509,6 +509,8 @@
<Compile Include="Criterion\QueryOverJoinBuilder.cs" />
<Compile Include="Criterion\QueryOverLockBuilder.cs" />
<Compile Include="Criterion\QueryOverOrderBuilder.cs" />
+ <Compile Include="Criterion\QueryOverSubqueryBuilder.cs" />
+ <Compile Include="Criterion\QueryOverSubqueryPropertyBuilder.cs" />
<Compile Include="Dialect\MsSql2008Dialect.cs" />
<Compile Include="Dialect\InformixDialect0940.cs" />
<Compile Include="Dialect\InformixDialect1000.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2009-11-05 17:19:23 UTC (rev 4820)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2009-11-05 17:46:33 UTC (rev 4821)
@@ -12,7 +12,7 @@
{
[TestFixture]
- public class TestExpressionProcessor
+ public class ExpressionProcessorFixture
{
[Test]
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/LambdaFixtureBase.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/LambdaFixtureBase.cs 2009-11-05 17:19:23 UTC (rev 4820)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/LambdaFixtureBase.cs 2009-11-05 17:46:33 UTC (rev 4821)
@@ -60,17 +60,21 @@
AssertObjectsAreEqual(expected, ((QueryOver<T>)actual).UnderlyingCriteria);
}
- protected void AssertCriteriaAreEqual<T>(DetachedCriteria expected, QueryOver<T> actual)
+ protected DetachedCriteria ToDetachedCriteria<T>(QueryOver<T> actual)
{
ICriteria criteria = actual.UnderlyingCriteria;
CriteriaImpl criteriaImpl = (CriteriaImpl)
typeof(QueryOver<T>).GetField("_impl", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(actual);
- DetachedCriteria actualDetached = (DetachedCriteria)
+ return (DetachedCriteria)
typeof(DetachedCriteria).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new System.Type[] { typeof(CriteriaImpl), typeof(ICriteria) }, null)
.Invoke(new object[] { criteriaImpl, criteria });
+ }
+ protected void AssertCriteriaAreEqual<T>(DetachedCriteria expected, QueryOver<T> actual)
+ {
+ DetachedCriteria actualDetached = ToDetachedCriteria(actual);
AssertObjectsAreEqual(expected, actualDetached);
}
Added: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-05 17:46:33 UTC (rev 4821)
@@ -0,0 +1,88 @@
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+using NHibernate.Criterion;
+using NHibernate.SqlCommand;
+using NHibernate.Transform;
+using NHibernate.Type;
+using NHibernate.Util;
+
+namespace NHibernate.Test.Criteria.Lambda
+{
+
+ [TestFixture]
+ public class SubqueryFixture : LambdaFixtureBase
+ {
+
+ private Person _subqueryPersonAlias = null;
+
+ private DetachedCriteria DetachedCriteriaPerson
+ {
+ get
+ {
+ return ToDetachedCriteria(DetachedQueryOverPerson);
+ }
+ }
+
+ private DetachedCriteria DetachedCriteriaName
+ {
+ get
+ {
+ return ToDetachedCriteria(DetachedQueryOverName);
+ }
+ }
+
+ private QueryOver<Person> DetachedQueryOverPerson
+ {
+ get
+ {
+ return
+ new QueryOver<Person>(() => _subqueryPersonAlias)
+ .Where(() => _subqueryPersonAlias.Name == "subquery name");
+ }
+ }
+
+ private QueryOver<Person> DetachedQueryOverName
+ {
+ get
+ {
+ return
+ new QueryOver<Person>(() => _subqueryPersonAlias)
+ .Where(() => _subqueryPersonAlias.Name == "subquery name")
+ .Select(p => p.Name);
+ }
+ }
+
+ [Test]
+ public void Property()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.WhereProperty(p => p.Name).Eq(DetachedQueryOverName);
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
+ public void PropertyAsSyntax()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.Where(p => p.Name == DetachedQueryOverName.As<string>());
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ }
+
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-05 17:19:23 UTC (rev 4820)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-05 17:46:33 UTC (rev 4821)
@@ -160,6 +160,7 @@
<Compile Include="Criteria\Lambda\IntegrationFixture.cs" />
<Compile Include="Criteria\Lambda\LambdaFixtureBase.cs" />
<Compile Include="Criteria\Lambda\Model.cs" />
+ <Compile Include="Criteria\Lambda\SubqueryFixture.cs" />
<Compile Include="Criteria\MaterialResource.cs" />
<Compile Include="Criteria\ProjectionsTest.cs" />
<Compile Include="Criteria\Reptile.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ste...@us...> - 2009-11-06 22:50:31
|
Revision: 4822
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4822&view=rev
Author: steverstrong
Date: 2009-11-06 22:50:19 +0000 (Fri, 06 Nov 2009)
Log Message:
-----------
Further Linq work - Support for Enumerable.Aggregate and various string functions (xxx.StartsWith etc)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs
trunk/nhibernate/src/NHibernate/Linq/HqlNodeStack.cs
trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs
trunk/nhibernate/src/NHibernate/Linq/ResultTransformer.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/Linq/AggregateTests.cs
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-05 17:46:33 UTC (rev 4821)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-06 22:50:19 UTC (rev 4822)
@@ -383,5 +383,20 @@
{
return new HqlAll(_factory);
}
+
+ public HqlLike Like()
+ {
+ return new HqlLike(_factory);
+ }
+
+ public HqlConcat Concat()
+ {
+ return new HqlConcat(_factory);
+ }
+
+ public HqlExpressionList ExpressionList()
+ {
+ return new HqlExpressionList(_factory);
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-05 17:46:33 UTC (rev 4821)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-06 22:50:19 UTC (rev 4822)
@@ -632,4 +632,18 @@
{
}
}
+
+ public class HqlLike : HqlTreeNode
+ {
+ public HqlLike(IASTFactory factory) : base(HqlSqlWalker.LIKE, "like", factory)
+ {
+ }
+ }
+
+ public class HqlConcat : HqlTreeNode
+ {
+ public HqlConcat(IASTFactory factory) : base(HqlSqlWalker.METHOD_CALL, "method", factory)
+ {
+ }
+ }
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs 2009-11-05 17:46:33 UTC (rev 4821)
+++ trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs 2009-11-06 22:50:19 UTC (rev 4822)
@@ -1,8 +1,28 @@
+using System;
using System.Linq;
+using System.Linq.Expressions;
using System.Reflection;
namespace NHibernate.Linq
{
+ public static class ReflectionHelper
+ {
+ public delegate void Action();
+
+ public static MethodInfo GetMethod<TSource>(Expression<Action<TSource>> method)
+ {
+ var methodInfo = ((MethodCallExpression) method.Body).Method;
+ return methodInfo.IsGenericMethod ? methodInfo.GetGenericMethodDefinition() : methodInfo;
+ }
+
+ public static MethodInfo GetMethod(Expression<Action> method)
+ {
+ var methodInfo = ((MethodCallExpression)method.Body).Method;
+ return methodInfo.IsGenericMethod ? methodInfo.GetGenericMethodDefinition() : methodInfo;
+ }
+ }
+
+ // TODO rename / remove - reflection helper above is better
public static class EnumerableHelper
{
public static MethodInfo GetMethod(string name, System.Type[] parameterTypes)
Modified: trunk/nhibernate/src/NHibernate/Linq/HqlNodeStack.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/HqlNodeStack.cs 2009-11-05 17:46:33 UTC (rev 4821)
+++ trunk/nhibernate/src/NHibernate/Linq/HqlNodeStack.cs 2009-11-06 22:50:19 UTC (rev 4822)
@@ -11,6 +11,7 @@
public HqlNodeStack(HqlTreeBuilder builder)
{
+ // TODO - only reason for the build is to have a root node. Sucks, change this
_root = builder.Holder();
_stack.Push(_root);
}
Modified: trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2009-11-05 17:46:33 UTC (rev 4821)
+++ trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2009-11-06 22:50:19 UTC (rev 4822)
@@ -1,16 +1,36 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using NHibernate.Engine.Query;
using NHibernate.Hql.Ast.ANTLR.Tree;
+using NHibernate.Linq.ResultOperators;
using NHibernate.Linq.Visitors;
+using Remotion.Data.Linq.Clauses;
+using Remotion.Data.Linq.Clauses.StreamedData;
using Remotion.Data.Linq.Parsing.ExpressionTreeVisitors;
using Remotion.Data.Linq.Parsing.Structure;
+using Remotion.Data.Linq.Parsing.Structure.IntermediateModel;
namespace NHibernate.Linq
{
public class NhLinqExpression : IQueryExpression
{
+ private static readonly MethodCallExpressionNodeTypeRegistry MethodCallRegistry =
+ MethodCallExpressionNodeTypeRegistry.CreateDefault();
+
+ static NhLinqExpression()
+ {
+ MethodCallRegistry.Register(
+ new[]
+ {
+ MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(ReflectionHelper.GetMethod(() => Queryable.Aggregate<object>(null, null))),
+ MethodCallExpressionNodeTypeRegistry.GetRegisterableMethodDefinition(ReflectionHelper.GetMethod(() => Queryable.Aggregate<object, object>(null, null, null)))
+ },
+ typeof (AggregateExpressionNode));
+ }
+
+
private readonly Expression _expression;
private CommandData _commandData;
private readonly IDictionary<ConstantExpression, NamedParameter> _queryParameters;
@@ -40,7 +60,8 @@
public IASTNode Translate(ISessionFactory sessionFactory)
{
var requiredHqlParameters = new List<NamedParameterDescriptor>();
- var queryModel = new QueryParser(new ExpressionTreeParser(MethodCallExpressionNodeTypeRegistry.CreateDefault())).GetParsedQuery(_expression);
+ // TODO - can we cache any of this?
+ var queryModel = new QueryParser(new ExpressionTreeParser(MethodCallRegistry)).GetParsedQuery(_expression);
_commandData = QueryModelVisitor.GenerateHqlQuery(queryModel, _queryParameters, requiredHqlParameters);
@@ -67,4 +88,65 @@
_commandData.AddAdditionalCriteria(impl);
}
}
+
+ public class AggregateExpressionNode : ResultOperatorExpressionNodeBase
+ {
+ public MethodCallExpressionParseInfo ParseInfo { get; set; }
+ public Expression OptionalSeed { get; set; }
+ public LambdaExpression Accumulator { get; set; }
+ public LambdaExpression OptionalSelector { get; set; }
+
+ public AggregateExpressionNode(MethodCallExpressionParseInfo parseInfo, Expression arg1, Expression arg2, LambdaExpression optionalSelector) : base(parseInfo, null, optionalSelector)
+ {
+ ParseInfo = parseInfo;
+
+ if (arg2 != null)
+ {
+ OptionalSeed = arg1;
+ Accumulator = (LambdaExpression) arg2;
+ }
+ else
+ {
+ Accumulator = (LambdaExpression) arg1;
+ }
+
+ OptionalSelector = optionalSelector;
+ }
+
+ public override Expression Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
+ {
+ return new AggregateResultOperator(ParseInfo, OptionalSeed, Accumulator, OptionalSelector);
+ }
+ }
+
+ public class AggregateResultOperator : ClientSideTransformOperator
+ {
+ public MethodCallExpressionParseInfo ParseInfo { get; set; }
+ public Expression OptionalSeed { get; set; }
+ public LambdaExpression Accumulator { get; set; }
+ public LambdaExpression OptionalSelector { get; set; }
+
+ public AggregateResultOperator(MethodCallExpressionParseInfo parseInfo, Expression optionalSeed, LambdaExpression accumulator, LambdaExpression optionalSelector)
+ {
+ ParseInfo = parseInfo;
+ OptionalSeed = optionalSeed;
+ Accumulator = accumulator;
+ OptionalSelector = optionalSelector;
+ }
+
+ public override IStreamedDataInfo GetOutputDataInfo(IStreamedDataInfo inputInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override ResultOperatorBase Clone(CloneContext cloneContext)
+ {
+ throw new NotImplementedException();
+ }
+ }
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/ResultTransformer.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/ResultTransformer.cs 2009-11-05 17:46:33 UTC (rev 4821)
+++ trunk/nhibernate/src/NHibernate/Linq/ResultTransformer.cs 2009-11-06 22:50:19 UTC (rev 4822)
@@ -1,7 +1,9 @@
using System;
using System.Collections;
+using System.Linq;
using System.Linq.Expressions;
using NHibernate.Transform;
+using Remotion.Collections;
namespace NHibernate.Linq
{
@@ -30,7 +32,38 @@
public IList TransformList(IList collection)
{
- return _listTransformation == null ? collection : (IList) _listTransformation.DynamicInvoke(collection);
+ if (_listTransformation == null)
+ {
+ return collection;
+ }
+
+ object transformResult = collection;
+
+ if (collection.Count > 0)
+ {
+ if (collection[0] is object[])
+ {
+ if ( ((object[])collection[0]).Length != 1)
+ {
+ // We only expect single items
+ throw new NotSupportedException();
+ }
+
+ transformResult = _listTransformation.DynamicInvoke(collection.Cast<object[]>().Select(o => o[0]));
+ }
+ else
+ {
+ transformResult = _listTransformation.DynamicInvoke(collection);
+ }
+ }
+
+ if (transformResult is IList)
+ {
+ return (IList) transformResult;
+ }
+
+ var list = new ArrayList {transformResult};
+ return list;
}
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-05 17:46:33 UTC (rev 4821)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-06 22:50:19 UTC (rev 4822)
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
+using System.Reflection;
using NHibernate.Engine.Query;
using NHibernate.Hql.Ast;
using NHibernate.Linq.Expressions;
-using NHibernate.Linq.ReWriters;
+using Remotion.Data.Linq;
using Remotion.Data.Linq.Clauses.Expressions;
using Remotion.Data.Linq.Clauses.ExpressionTreeVisitors;
@@ -17,8 +19,9 @@
protected readonly HqlNodeStack _stack;
private readonly IDictionary<ConstantExpression, NamedParameter> _parameters;
private readonly IList<NamedParameterDescriptor> _requiredHqlParameters;
+ static private readonly MethodGeneratorRegistry _methodGeneratorRegistry = MethodGeneratorRegistry.Initialise();
- public HqlGeneratorExpressionTreeVisitor(IDictionary<ConstantExpression, NamedParameter> parameters, IList<NamedParameterDescriptor> requiredHqlParameters)
+ public HqlGeneratorExpressionTreeVisitor(IDictionary<ConstantExpression, NamedParameter> parameters, IList<NamedParameterDescriptor> requiredHqlParameters)
{
_parameters = parameters;
_requiredHqlParameters = requiredHqlParameters;
@@ -36,6 +39,16 @@
VisitExpression(expression);
}
+ public HqlNodeStack Stack
+ {
+ get { return _stack; }
+ }
+
+ public HqlTreeBuilder TreeBuilder
+ {
+ get { return _hqlTreeBuilder; }
+ }
+
protected override Expression VisitNhAverage(NhAverageExpression expression)
{
var visitor = new HqlGeneratorExpressionTreeVisitor(_parameters, _requiredHqlParameters);
@@ -238,106 +251,11 @@
protected override Expression VisitMethodCallExpression(MethodCallExpression expression)
{
- if (expression.Method.DeclaringType == typeof(Enumerable) ||
- expression.Method.DeclaringType == typeof(Queryable))
- {
- switch (expression.Method.Name)
- {
- case "Any":
- // Any has one or two arguments. Arg 1 is the source and arg 2 is the optional predicate
- using (_stack.PushNode(_hqlTreeBuilder.Exists()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.Query()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.SelectFrom()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.From()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.Range()))
- {
- VisitExpression(expression.Arguments[0]);
+ var generator = _methodGeneratorRegistry.GetMethodGenerator(expression.Method);
- if (expression.Arguments.Count > 1)
- {
- var expr = (LambdaExpression) expression.Arguments[1];
- _stack.PushLeaf(_hqlTreeBuilder.Alias(expr.Parameters[0].Name));
- }
- }
- }
- }
- if (expression.Arguments.Count > 1)
- {
- using (_stack.PushNode(_hqlTreeBuilder.Where()))
- {
- VisitExpression(expression.Arguments[1]);
- }
- }
- }
- }
- break;
+ generator.BuildHql(expression.Object, expression.Arguments, this);
- case "All":
- // All has one or two arguments. Arg 1 is the source and arg 2 is the optional predicate
- using (_stack.PushNode(_hqlTreeBuilder.Not()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.Exists()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.Query()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.SelectFrom()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.From()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.Range()))
- {
- VisitExpression(expression.Arguments[0]);
-
- if (expression.Arguments.Count > 1)
- {
- var expr = (LambdaExpression) expression.Arguments[1];
-
- _stack.PushLeaf(_hqlTreeBuilder.Alias(expr.Parameters[0].Name));
- }
- }
- }
- }
- if (expression.Arguments.Count > 1)
- {
- using (_stack.PushNode(_hqlTreeBuilder.Where()))
- {
- using (_stack.PushNode(_hqlTreeBuilder.Not()))
- {
- VisitExpression(expression.Arguments[1]);
- }
- }
- }
- }
- }
- }
- break;
-
- case "Min":
- using (_stack.PushNode(_hqlTreeBuilder.Min()))
- {
- VisitExpression(expression.Arguments[1]);
- }
- break;
- case "Max":
- using (_stack.PushNode(_hqlTreeBuilder.Max()))
- {
- VisitExpression(expression.Arguments[1]);
- }
- break;
- default:
- throw new NotSupportedException(string.Format("The Enumerable method {0} is not supported", expression.Method.Name));
- }
-
- return expression;
- }
- else
- {
- return base.VisitMethodCallExpression(expression); // throws
- }
+ return expression;
}
protected override Expression VisitLambdaExpression(LambdaExpression expression)
@@ -401,4 +319,352 @@
return itemAsExpression != null ? FormattingExpressionTreeVisitor.Format(itemAsExpression) : unhandledItem.ToString();
}
}
+
+ public class MethodGeneratorRegistry
+ {
+ public static MethodGeneratorRegistry Initialise()
+ {
+ var registry = new MethodGeneratorRegistry();
+
+ // TODO - could use reflection here
+ registry.Register(new QueryableMethodsGenerator());
+ registry.Register(new StringMethodsGenerator());
+
+ return registry;
+ }
+
+ private readonly Dictionary<MethodInfo, IHqlGeneratorForMethod> _registeredMethods = new Dictionary<MethodInfo, IHqlGeneratorForMethod>();
+
+ public IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method)
+ {
+ IHqlGeneratorForMethod methodGenerator;
+
+ if (method.IsGenericMethod)
+ {
+ method = method.GetGenericMethodDefinition();
+ }
+
+ if (_registeredMethods.TryGetValue(method, out methodGenerator))
+ {
+ return methodGenerator;
+ }
+
+ throw new NotSupportedException();
+ }
+
+ public void RegisterMethodGenerator(MethodInfo method, IHqlGeneratorForMethod generator)
+ {
+ _registeredMethods.Add(method, generator);
+ }
+
+ private void Register(IHqlGeneratorForType typeMethodGenerator)
+ {
+ typeMethodGenerator.RegisterMethods(this);
+ }
+
+ }
+
+ public interface IHqlGeneratorForMethod
+ {
+ IEnumerable<MethodInfo> SupportedMethods { get; }
+ void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor);
+ }
+
+ public interface IHqlGeneratorForType
+ {
+ void RegisterMethods(MethodGeneratorRegistry methodGeneratorRegistry);
+ }
+
+ abstract public class BaseHqlGeneratorForType : IHqlGeneratorForType
+ {
+ protected readonly List<IHqlGeneratorForMethod> MethodRegistry = new List<IHqlGeneratorForMethod>();
+
+ public void RegisterMethods(MethodGeneratorRegistry methodGeneratorRegistry)
+ {
+ foreach (var generator in MethodRegistry)
+ {
+ foreach (var method in generator.SupportedMethods)
+ {
+ methodGeneratorRegistry.RegisterMethodGenerator(method, generator);
+ }
+ }
+ }
+ }
+
+ public abstract class BaseHqlGeneratorForMethod : IHqlGeneratorForMethod
+ {
+ public IEnumerable<MethodInfo> SupportedMethods { get; protected set; }
+
+ public abstract void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor);
+ }
+
+ public class StringMethodsGenerator : BaseHqlGeneratorForType
+ {
+ public StringMethodsGenerator()
+ {
+ // TODO - could use reflection
+ MethodRegistry.Add(new StartsWithGenerator());
+ MethodRegistry.Add(new EndsWithGenerator());
+ MethodRegistry.Add(new ContainsGenerator());
+ MethodRegistry.Add(new EqualsGenerator());
+ }
+
+ class StartsWithGenerator : BaseHqlGeneratorForMethod
+ {
+ public StartsWithGenerator()
+ {
+ SupportedMethods = new[] { ReflectionHelper.GetMethod<string>(x => x.StartsWith(null)) };
+ }
+
+ public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Like()))
+ {
+ hqlVisitor.Visit(targetObject);
+
+ // TODO - this sucks. Concat() just pushes a method node, and we have to do all the child stuff.
+ // Sort out the tree stuff so it works properly
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Concat()))
+ {
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Ident("concat"));
+
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.ExpressionList()))
+ {
+ hqlVisitor.Visit(arguments[0]);
+
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Constant("%"));
+ }
+ }
+ }
+ }
+ }
+
+ class EndsWithGenerator : BaseHqlGeneratorForMethod
+ {
+ public EndsWithGenerator()
+ {
+ SupportedMethods = new[] { ReflectionHelper.GetMethod<string>(x => x.EndsWith(null)) };
+ }
+
+ public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Like()))
+ {
+ hqlVisitor.Visit(targetObject);
+
+ // TODO - this sucks. Concat() just pushes a method node, and we have to do all the child stuff.
+ // Sort out the tree stuff so it works properly
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Concat()))
+ {
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Ident("concat"));
+
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.ExpressionList()))
+ {
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Constant("%"));
+
+ hqlVisitor.Visit(arguments[0]);
+ }
+ }
+ }
+ }
+ }
+
+ class ContainsGenerator : BaseHqlGeneratorForMethod
+ {
+ public ContainsGenerator()
+ {
+ SupportedMethods = new[] { ReflectionHelper.GetMethod<string>(x => x.Contains(null)) };
+ }
+
+ public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Like()))
+ {
+ hqlVisitor.Visit(targetObject);
+
+ // TODO - this sucks. Concat() just pushes a method node, and we have to do all the child stuff.
+ // Sort out the tree stuff so it works properly
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Concat()))
+ {
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Ident("concat"));
+
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.ExpressionList()))
+ {
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Constant("%"));
+
+ hqlVisitor.Visit(arguments[0]);
+
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Constant("%"));
+ }
+ }
+ }
+ }
+ }
+
+ class EqualsGenerator : BaseHqlGeneratorForMethod
+ {
+ public EqualsGenerator()
+ {
+ SupportedMethods = new[] { ReflectionHelper.GetMethod<string>(x => x.Equals((string)null)) };
+ }
+
+ public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Equality()))
+ {
+ hqlVisitor.Visit(targetObject);
+
+ hqlVisitor.Visit(arguments[0]);
+ }
+ }
+ }
+ }
+
+ public class QueryableMethodsGenerator : BaseHqlGeneratorForType
+ {
+ public QueryableMethodsGenerator()
+ {
+ // TODO - could use reflection
+ MethodRegistry.Add(new AnyGenerator());
+ MethodRegistry.Add(new AllGenerator());
+ MethodRegistry.Add(new MinGenerator());
+ MethodRegistry.Add(new MaxGenerator());
+ }
+
+ class AnyGenerator : BaseHqlGeneratorForMethod
+ {
+ public AnyGenerator()
+ {
+ SupportedMethods = new[]
+ {
+ ReflectionHelper.GetMethod(() => Queryable.Any<object>(null)),
+ ReflectionHelper.GetMethod(() => Queryable.Any<object>(null, null)),
+ ReflectionHelper.GetMethod(() => Enumerable.Any<object>(null)),
+ ReflectionHelper.GetMethod(() => Enumerable.Any<object>(null, null))
+ };
+ }
+
+ public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ {
+ // Any has one or two arguments. Arg 1 is the source and arg 2 is the optional predicate
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Exists()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Query()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.SelectFrom()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.From()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Range()))
+ {
+ hqlVisitor.Visit(arguments[0]);
+
+ if (arguments.Count > 1)
+ {
+ var expr = (LambdaExpression)arguments[1];
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Alias(expr.Parameters[0].Name));
+ }
+ }
+ }
+ }
+ if (arguments.Count > 1)
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Where()))
+ {
+ hqlVisitor.Visit(arguments[1]);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ class AllGenerator : BaseHqlGeneratorForMethod
+ {
+ public AllGenerator()
+ {
+ SupportedMethods = new[]
+ {
+ ReflectionHelper.GetMethod(() => Queryable.All<object>(null, null)),
+ ReflectionHelper.GetMethod(() => Enumerable.All<object>(null, null))
+ };
+ }
+
+ public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ {
+ // All has two arguments. Arg 1 is the source and arg 2 is the predicate
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Not()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Exists()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Query()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.SelectFrom()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.From()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Range()))
+ {
+ hqlVisitor.Visit(arguments[0]);
+
+ var expr = (LambdaExpression)arguments[1];
+
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Alias(expr.Parameters[0].Name));
+ }
+ }
+ }
+
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Where()))
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Not()))
+ {
+ ...
[truncated message content] |
|
From: <ric...@us...> - 2009-11-07 12:43:19
|
Revision: 4823
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4823&view=rev
Author: ricbrown
Date: 2009-11-07 12:43:07 +0000 (Sat, 07 Nov 2009)
Log Message:
-----------
Fleshed out Subquery overloads for QueryOver.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-06 22:50:19 UTC (rev 4822)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-07 12:43:07 UTC (rev 4823)
@@ -66,7 +66,7 @@
/// Method to allow comparison of detached query in Lambda expression
/// e.g., p => p.Name == myQuery.As<string>
/// </summary>
- /// <typeparam name="T">type returned by query</typeparam>
+ /// <typeparam name="R">type returned by query</typeparam>
/// <returns>throws an exception if evaluated directly at runtime.</returns>
public R As<R>()
{
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs 2009-11-06 22:50:19 UTC (rev 4822)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs 2009-11-07 12:43:07 UTC (rev 4823)
@@ -51,9 +51,14 @@
public S WhereProperty(Expression<Func<T, object>> expression)
{
string property = ExpressionProcessor.FindMemberExpression(expression.Body);
- return (S) new S().Set(root, property);
+ return (S)new S().Set(root, property, null);
}
+ public S WhereValue(object value)
+ {
+ return (S)new S().Set(root, null, value);
+ }
+
}
}
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs 2009-11-06 22:50:19 UTC (rev 4822)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs 2009-11-07 12:43:07 UTC (rev 4823)
@@ -29,7 +29,7 @@
{
protected QueryOverSubqueryPropertyBuilderBase() { }
- public abstract QueryOverSubqueryPropertyBuilderBase Set(object root, string path);
+ internal abstract QueryOverSubqueryPropertyBuilderBase Set(object root, string path, object value);
}
public class QueryOverSubqueryPropertyBuilderBase<R, T> : QueryOverSubqueryPropertyBuilderBase
@@ -38,28 +38,115 @@
protected R root;
protected string path;
+ protected object value;
protected QueryOverSubqueryPropertyBuilderBase()
{
}
- public override QueryOverSubqueryPropertyBuilderBase Set(object root, string path)
+ internal override QueryOverSubqueryPropertyBuilderBase Set(object root, string path, object value)
{
this.root = (R)root;
this.path = path;
+ this.value = value;
return this;
}
+ private void AddSubquery<U>(
+ Func<string, DetachedCriteria, AbstractCriterion> propertyMethod,
+ Func<object, DetachedCriteria, AbstractCriterion> valueMethod,
+ QueryOver<U> detachedCriteria)
+ {
+ if (path != null)
+ {
+ root.And(propertyMethod(path, detachedCriteria.DetachedCriteria));
+ }
+ else
+ {
+ root.And(valueMethod(value, detachedCriteria.DetachedCriteria));
+ }
+ }
+
/// <summary>
/// Add a property equal subquery criterion
/// </summary>
/// <param name="detachedCriteria">detached subquery</param>
- public R Eq(QueryOver<T> detachedCriteria)
+ public R Eq<U>(QueryOver<U> detachedCriteria)
{
- root.Where(Subqueries.PropertyEq(path, detachedCriteria.DetachedCriteria));
+ AddSubquery(Subqueries.PropertyEq, Subqueries.Eq, detachedCriteria);
return root;
}
+ /// <summary>
+ /// Create a property greater than or equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Ge<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyGe, Subqueries.Ge, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property greater than subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Gt<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyGt, Subqueries.Gt, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property in subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R In<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyIn, Subqueries.In, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property less than or equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Le<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyLe, Subqueries.Le, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property less than subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Lt<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyLt, Subqueries.Lt, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property not equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Ne<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyNe, Subqueries.Ne, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property not in subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R NotIn<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyNotIn, Subqueries.NotIn, detachedCriteria);
+ return root;
+ }
+
}
}
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2009-11-06 22:50:19 UTC (rev 4822)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2009-11-07 12:43:07 UTC (rev 4823)
@@ -35,6 +35,7 @@
{
public virtual int Id { get; set; }
public virtual string Nickname { get; set; }
+ public virtual int Age { get; set; }
}
public class Relation
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-06 22:50:19 UTC (rev 4822)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-07 12:43:07 UTC (rev 4823)
@@ -16,13 +16,13 @@
public class SubqueryFixture : LambdaFixtureBase
{
- private Person _subqueryPersonAlias = null;
+ private Child _subqueryChildAlias = null;
- private DetachedCriteria DetachedCriteriaPerson
+ private DetachedCriteria DetachedCriteriaChild
{
get
{
- return ToDetachedCriteria(DetachedQueryOverPerson);
+ return ToDetachedCriteria(DetachedQueryOverChild);
}
}
@@ -34,37 +34,70 @@
}
}
- private QueryOver<Person> DetachedQueryOverPerson
+ private DetachedCriteria DetachedCriteriaAge
{
get
{
+ return ToDetachedCriteria(DetachedQueryOverAge);
+ }
+ }
+
+ private QueryOver<Child> DetachedQueryOverChild
+ {
+ get
+ {
return
- new QueryOver<Person>(() => _subqueryPersonAlias)
- .Where(() => _subqueryPersonAlias.Name == "subquery name");
+ new QueryOver<Child>(() => _subqueryChildAlias)
+ .Where(() => _subqueryChildAlias.Nickname == "subquery name");
}
}
- private QueryOver<Person> DetachedQueryOverName
+ private QueryOver<Child> DetachedQueryOverName
{
get
{
return
- new QueryOver<Person>(() => _subqueryPersonAlias)
- .Where(() => _subqueryPersonAlias.Name == "subquery name")
- .Select(p => p.Name);
+ new QueryOver<Child>(() => _subqueryChildAlias)
+ .Where(() => _subqueryChildAlias.Nickname == "subquery name")
+ .Select(p => p.Nickname);
}
}
+ private QueryOver<Child> DetachedQueryOverAge
+ {
+ get
+ {
+ return
+ new QueryOver<Child>(() => _subqueryChildAlias)
+ .Where(() => _subqueryChildAlias.Nickname == "subquery name")
+ .Select(p => p.Age);
+ }
+ }
+
[Test]
public void Property()
{
ICriteria expected =
CreateTestCriteria(typeof(Person))
- .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName));
+ .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyGe("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGt("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyIn("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyLe("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLt("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyNe("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyNotIn("Name", DetachedCriteriaName));
var actual =
CreateTestQueryOver<Person>()
- .WithSubquery.WhereProperty(p => p.Name).Eq(DetachedQueryOverName);
+ .WithSubquery.WhereProperty(p => p.Name).Eq(DetachedQueryOverName)
+ .WithSubquery.WhereProperty(p => p.Age).Ge(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Age).Gt(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Name).In(DetachedQueryOverName)
+ .WithSubquery.WhereProperty(p => p.Age).Le(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Age).Lt(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Name).Ne(DetachedQueryOverName)
+ .WithSubquery.WhereProperty(p => p.Name).NotIn(DetachedQueryOverName);
AssertCriteriaAreEqual(expected, actual);
}
@@ -74,15 +107,53 @@
{
ICriteria expected =
CreateTestCriteria(typeof(Person))
- .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName));
+ .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyNe("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyGe("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGt("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLe("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLt("Age", DetachedCriteriaAge));
var actual =
CreateTestQueryOver<Person>()
- .WithSubquery.Where(p => p.Name == DetachedQueryOverName.As<string>());
+ .WithSubquery.Where(p => p.Name == DetachedQueryOverName.As<string>())
+ .WithSubquery.Where(p => p.Name != DetachedQueryOverName.As<string>())
+ .WithSubquery.Where(p => p.Age >= DetachedQueryOverAge.As<int>())
+ .WithSubquery.Where(p => p.Age > DetachedQueryOverAge.As<int>())
+ .WithSubquery.Where(p => p.Age <= DetachedQueryOverAge.As<int>())
+ .WithSubquery.Where(p => p.Age < DetachedQueryOverAge.As<int>());
AssertCriteriaAreEqual(expected, actual);
}
+ [Test]
+ public void Value()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.Eq("Name", DetachedCriteriaName))
+ .Add(Subqueries.Ge("Age", DetachedCriteriaAge))
+ .Add(Subqueries.Gt("Age", DetachedCriteriaAge))
+ .Add(Subqueries.In("Name", DetachedCriteriaName))
+ .Add(Subqueries.Le("Age", DetachedCriteriaAge))
+ .Add(Subqueries.Lt("Age", DetachedCriteriaAge))
+ .Add(Subqueries.Ne("Name", DetachedCriteriaName))
+ .Add(Subqueries.NotIn("Name", DetachedCriteriaName));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.WhereValue("Name").Eq(DetachedQueryOverName)
+ .WithSubquery.WhereValue("Age").Ge(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Age").Gt(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Name").In(DetachedQueryOverName)
+ .WithSubquery.WhereValue("Age").Le(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Age").Lt(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Name").Ne(DetachedQueryOverName)
+ .WithSubquery.WhereValue("Name").NotIn(DetachedQueryOverName);
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-08 10:58:56
|
Revision: 4824
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4824&view=rev
Author: ricbrown
Date: 2009-11-08 10:58:42 +0000 (Sun, 08 Nov 2009)
Log Message:
-----------
Minor change to QueryOver CreateAlias() syntax.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOverJoinBuilder.cs
trunk/nhibernate/src/NHibernate/IQueryOver.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-07 12:43:07 UTC (rev 4823)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-08 10:58:42 UTC (rev 4824)
@@ -318,7 +318,7 @@
joinType));
}
- public QueryOver<T> Join(Expression<Func<T, object>> path, Expression<Func<object>> alias)
+ public QueryOver<T> JoinAlias(Expression<Func<T, object>> path, Expression<Func<object>> alias)
{
return AddAlias(
ExpressionProcessor.FindMemberExpression(path.Body),
@@ -326,7 +326,7 @@
JoinType.InnerJoin);
}
- public QueryOver<T> Join(Expression<Func<object>> path, Expression<Func<object>> alias)
+ public QueryOver<T> JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias)
{
return AddAlias(
ExpressionProcessor.FindMemberExpression(path.Body),
@@ -334,7 +334,7 @@
JoinType.InnerJoin);
}
- public QueryOver<T> Join(Expression<Func<T, object>> path, Expression<Func<object>> alias, JoinType joinType)
+ public QueryOver<T> JoinAlias(Expression<Func<T, object>> path, Expression<Func<object>> alias, JoinType joinType)
{
return AddAlias(
ExpressionProcessor.FindMemberExpression(path.Body),
@@ -342,7 +342,7 @@
joinType);
}
- public QueryOver<T> Join(Expression<Func<object>> path, Expression<Func<object>> alias, JoinType joinType)
+ public QueryOver<T> JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias, JoinType joinType)
{
return AddAlias(
ExpressionProcessor.FindMemberExpression(path.Body),
@@ -558,17 +558,17 @@
IQueryOver<U> IQueryOver<T>.JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias, JoinType joinType)
{ return JoinQueryOver(path, alias, joinType); }
- IQueryOver<T> IQueryOver<T>.Join(Expression<Func<T, object>> path, Expression<Func<object>> alias)
- { return Join(path, alias); }
+ IQueryOver<T> IQueryOver<T>.JoinAlias(Expression<Func<T, object>> path, Expression<Func<object>> alias)
+ { return JoinAlias(path, alias); }
- IQueryOver<T> IQueryOver<T>.Join(Expression<Func<object>> path, Expression<Func<object>> alias)
- { return Join(path, alias); }
+ IQueryOver<T> IQueryOver<T>.JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias)
+ { return JoinAlias(path, alias); }
- IQueryOver<T> IQueryOver<T>.Join(Expression<Func<T, object>> path, Expression<Func<object>> alias, JoinType joinType)
- { return Join(path, alias, joinType); }
+ IQueryOver<T> IQueryOver<T>.JoinAlias(Expression<Func<T, object>> path, Expression<Func<object>> alias, JoinType joinType)
+ { return JoinAlias(path, alias, joinType); }
- IQueryOver<T> IQueryOver<T>.Join(Expression<Func<object>> path, Expression<Func<object>> alias, JoinType joinType)
- { return Join(path, alias, joinType); }
+ IQueryOver<T> IQueryOver<T>.JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias, JoinType joinType)
+ { return JoinAlias(path, alias, joinType); }
IQueryOverJoinBuilder<T> IQueryOver<T>.Inner
{ get { return new IQueryOverJoinBuilder<T>(this, JoinType.InnerJoin); } }
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOverJoinBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverJoinBuilder.cs 2009-11-07 12:43:07 UTC (rev 4823)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverJoinBuilder.cs 2009-11-08 10:58:42 UTC (rev 4824)
@@ -113,14 +113,14 @@
this.joinType = joinType;
}
- public R Join(Expression<Func<T, object>> path, Expression<Func<object>> alias)
+ public R JoinAlias(Expression<Func<T, object>> path, Expression<Func<object>> alias)
{
- return (R)root.Join(path, alias, joinType);
+ return (R)root.JoinAlias(path, alias, joinType);
}
- public R Join(Expression<Func<object>> path, Expression<Func<object>> alias)
+ public R JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias)
{
- return (R)root.Join(path, alias, joinType);
+ return (R)root.JoinAlias(path, alias, joinType);
}
}
Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-07 12:43:07 UTC (rev 4823)
+++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-08 10:58:42 UTC (rev 4824)
@@ -317,7 +317,7 @@
/// <param name="path">Lambda expression returning association path</param>
/// <param name="alias">Lambda expression returning alias reference</param>
/// <returns>criteria instance</returns>
- IQueryOver<T> Join(Expression<Func<T, object>> path, Expression<Func<object>> alias);
+ IQueryOver<T> JoinAlias(Expression<Func<T, object>> path, Expression<Func<object>> alias);
/// <summary>
/// Join an association, assigning an alias to the joined entity
@@ -325,7 +325,7 @@
/// <param name="path">Lambda expression returning association path</param>
/// <param name="alias">Lambda expression returning alias reference</param>
/// <returns>criteria instance</returns>
- IQueryOver<T> Join(Expression<Func<object>> path, Expression<Func<object>> alias);
+ IQueryOver<T> JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias);
/// <summary>
/// Join an association, assigning an alias to the joined entity
@@ -334,7 +334,7 @@
/// <param name="alias">Lambda expression returning alias reference</param>
/// <param name="joinType">Type of join</param>
/// <returns>criteria instance</returns>
- IQueryOver<T> Join(Expression<Func<T, object>> path, Expression<Func<object>> alias, JoinType joinType);
+ IQueryOver<T> JoinAlias(Expression<Func<T, object>> path, Expression<Func<object>> alias, JoinType joinType);
/// <summary>
/// Join an association, assigning an alias to the joined entity
@@ -343,7 +343,7 @@
/// <param name="alias">Lambda expression returning alias reference</param>
/// <param name="joinType">Type of join</param>
/// <returns>criteria instance</returns>
- IQueryOver<T> Join(Expression<Func<object>> path, Expression<Func<object>> alias, JoinType joinType);
+ IQueryOver<T> JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias, JoinType joinType);
IQueryOverJoinBuilder<T> Inner { get; }
IQueryOverJoinBuilder<T> Left { get; }
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-07 12:43:07 UTC (rev 4823)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-08 10:58:42 UTC (rev 4824)
@@ -270,8 +270,8 @@
Child childAlias = null;
IQueryOver<Person> actual =
CreateTestQueryOver<Person>()
- .Join(p => p.Father, () => fatherAlias)
- .Join(p => p.Children, () => childAlias);
+ .JoinAlias(p => p.Father, () => fatherAlias)
+ .JoinAlias(p => p.Children, () => childAlias);
AssertCriteriaAreEqual(expected, actual);
}
@@ -289,8 +289,8 @@
Child childAlias = null;
IQueryOver<Person> actual =
CreateTestQueryOver<Person>(() => personAlias)
- .Join(() => personAlias.Father, () => fatherAlias)
- .Inner.Join(() => personAlias.Children, () => childAlias);
+ .JoinAlias(() => personAlias.Father, () => fatherAlias)
+ .Inner.JoinAlias(() => personAlias.Children, () => childAlias);
AssertCriteriaAreEqual(expected, actual);
}
@@ -313,14 +313,14 @@
Relation collection1Alias = null, collection2Alias = null, collection3Alias = null, collection4Alias = null;
IQueryOver<Relation> actual =
CreateTestQueryOver<Relation>()
- .Inner.Join(r => r.Related1, () => related1Alias)
- .Inner.Join(r => r.Collection1, () => collection1Alias)
- .Left.Join(r => r.Related2, () => related2Alias)
- .Left.Join(r => r.Collection2, () => collection2Alias)
- .Right.Join(r => r.Related3, () => related3Alias)
- .Right.Join(r => r.Collection3, () => collection3Alias)
- .Full.Join(r => r.Related4, () => related4Alias)
- .Full.Join(r => r.Collection4, () => collection4Alias);
+ .Inner.JoinAlias(r => r.Related1, () => related1Alias)
+ .Inner.JoinAlias(r => r.Collection1, () => collection1Alias)
+ .Left.JoinAlias(r => r.Related2, () => related2Alias)
+ .Left.JoinAlias(r => r.Collection2, () => collection2Alias)
+ .Right.JoinAlias(r => r.Related3, () => related3Alias)
+ .Right.JoinAlias(r => r.Collection3, () => collection3Alias)
+ .Full.JoinAlias(r => r.Related4, () => related4Alias)
+ .Full.JoinAlias(r => r.Collection4, () => collection4Alias);
AssertCriteriaAreEqual(expected, actual);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-10 13:32:39
|
Revision: 4825
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4825&view=rev
Author: ricbrown
Date: 2009-11-10 13:32:28 +0000 (Tue, 10 Nov 2009)
Log Message:
-----------
Tidied QueryOver builder classes inside separate folder/namespace.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate/IQueryOver.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/Lambda/
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverFetchBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverJoinBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverLockBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs
Removed Paths:
-------------
trunk/nhibernate/src/NHibernate/Criterion/QueryOverFetchBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOverJoinBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOverLockBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOverOrderBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs
Copied: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverFetchBuilder.cs (from rev 4822, trunk/nhibernate/src/NHibernate/Criterion/QueryOverFetchBuilder.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverFetchBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverFetchBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -0,0 +1,69 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion
+{
+
+ public class QueryOverFetchBuilder<T> : QueryOverFetchBuilderBase<QueryOver<T>, T>
+ {
+
+ public QueryOverFetchBuilder(QueryOver<T> root, Expression<Func<T, object>> path)
+ : base(root, path) { }
+
+ }
+
+ public class IQueryOverFetchBuilder<T> : QueryOverFetchBuilderBase<IQueryOver<T>, T>
+ {
+
+ public IQueryOverFetchBuilder(IQueryOver<T> root, Expression<Func<T, object>> path)
+ : base(root, path) { }
+
+ }
+
+ public class QueryOverFetchBuilderBase<R, T> where R : IQueryOver<T>
+ {
+
+ protected R root;
+ protected string path;
+
+ protected QueryOverFetchBuilderBase(R root, Expression<Func<T, object>> path)
+ {
+ this.root = root;
+ this.path = ExpressionProcessor.FindMemberExpression(path.Body);
+ }
+
+ public R Eager
+ {
+ get
+ {
+ this.root.UnderlyingCriteria.SetFetchMode(path, FetchMode.Eager);
+ return this.root;
+ }
+ }
+
+ public R Lazy
+ {
+ get
+ {
+ this.root.UnderlyingCriteria.SetFetchMode(path, FetchMode.Lazy);
+ return this.root;
+ }
+ }
+
+ public R Default
+ {
+ get
+ {
+ this.root.UnderlyingCriteria.SetFetchMode(path, FetchMode.Default);
+ return this.root;
+ }
+ }
+
+ }
+
+}
Copied: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverJoinBuilder.cs (from rev 4824, trunk/nhibernate/src/NHibernate/Criterion/QueryOverJoinBuilder.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverJoinBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverJoinBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -0,0 +1,128 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class QueryOverJoinBuilder<T> : QueryOverJoinBuilderBase<QueryOver<T>, T>
+ {
+ public QueryOverJoinBuilder(QueryOver<T> root, JoinType joinType) : base(root, joinType) { }
+
+ public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path)
+ {
+ return root.JoinQueryOver<U>(path, joinType);
+ }
+
+ public QueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path)
+ {
+ return root.JoinQueryOver<U>(path, joinType);
+ }
+
+ public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path, Expression<Func<U>> alias)
+ {
+ return root.JoinQueryOver<U>(path, alias, joinType);
+ }
+
+ public QueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias)
+ {
+ return root.JoinQueryOver<U>(path, alias, joinType);
+ }
+
+ public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path)
+ {
+ return root.JoinQueryOver<U>(path, joinType);
+ }
+
+ public QueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path)
+ {
+ return root.JoinQueryOver<U>(path, joinType);
+ }
+
+ public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path, Expression<Func<U>> alias)
+ {
+ return root.JoinQueryOver<U>(path, alias, joinType);
+ }
+
+ public QueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias)
+ {
+ return root.JoinQueryOver<U>(path, alias, joinType);
+ }
+
+ }
+
+ public class IQueryOverJoinBuilder<T> : QueryOverJoinBuilderBase<IQueryOver<T>, T>
+ {
+ public IQueryOverJoinBuilder(IQueryOver<T> root, JoinType joinType) : base(root, joinType) { }
+
+ public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path)
+ {
+ return root.JoinQueryOver<U>(path, joinType);
+ }
+
+ public IQueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path)
+ {
+ return root.JoinQueryOver<U>(path, joinType);
+ }
+
+ public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path, Expression<Func<U>> alias)
+ {
+ return root.JoinQueryOver<U>(path, alias, joinType);
+ }
+
+ public IQueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias)
+ {
+ return root.JoinQueryOver<U>(path, alias, joinType);
+ }
+
+ public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path)
+ {
+ return root.JoinQueryOver<U>(path, joinType);
+ }
+
+ public IQueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path)
+ {
+ return root.JoinQueryOver<U>(path, joinType);
+ }
+
+ public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path, Expression<Func<U>> alias)
+ {
+ return root.JoinQueryOver<U>(path, alias, joinType);
+ }
+
+ public IQueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias)
+ {
+ return root.JoinQueryOver<U>(path, alias, joinType);
+ }
+
+ }
+
+ public class QueryOverJoinBuilderBase<R, T> where R : IQueryOver<T>
+ {
+
+ protected R root;
+ protected JoinType joinType;
+
+ public QueryOverJoinBuilderBase(R root, JoinType joinType)
+ {
+ this.root = root;
+ this.joinType = joinType;
+ }
+
+ public R JoinAlias(Expression<Func<T, object>> path, Expression<Func<object>> alias)
+ {
+ return (R)root.JoinAlias(path, alias, joinType);
+ }
+
+ public R JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias)
+ {
+ return (R)root.JoinAlias(path, alias, joinType);
+ }
+
+ }
+
+}
Copied: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverLockBuilder.cs (from rev 4822, trunk/nhibernate/src/NHibernate/Criterion/QueryOverLockBuilder.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverLockBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverLockBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -0,0 +1,106 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class QueryOverLockBuilder<T> : QueryOverLockBuilderBase<QueryOver<T>, T>
+ {
+
+ public QueryOverLockBuilder(QueryOver<T> root, Expression<Func<object>> alias)
+ : base(root, alias) { }
+
+ }
+
+ public class IQueryOverLockBuilder<T> : QueryOverLockBuilderBase<IQueryOver<T>, T>
+ {
+
+ public IQueryOverLockBuilder(IQueryOver<T> root, Expression<Func<object>> alias)
+ : base(root, alias) { }
+
+ }
+
+ public class QueryOverLockBuilderBase<R, T> where R : IQueryOver<T>
+ {
+
+ protected R root;
+ protected string alias;
+
+ protected QueryOverLockBuilderBase(R root, Expression<Func<object>> alias)
+ {
+ this.root = root;
+
+ if (alias != null)
+ this.alias = ExpressionProcessor.FindMemberExpression(alias.Body);
+ }
+
+ private void SetLockMode(LockMode lockMode)
+ {
+ if (alias != null)
+ root.UnderlyingCriteria.SetLockMode(alias, lockMode);
+ else
+ root.UnderlyingCriteria.SetLockMode(lockMode);
+ }
+
+ public R Force
+ {
+ get
+ {
+ SetLockMode(LockMode.Force);
+ return this.root;
+ }
+ }
+
+ public R None
+ {
+ get
+ {
+ SetLockMode(LockMode.None);
+ return this.root;
+ }
+ }
+
+ public R Read
+ {
+ get
+ {
+ SetLockMode(LockMode.Read);
+ return this.root;
+ }
+ }
+
+ public R Upgrade
+ {
+ get
+ {
+ SetLockMode(LockMode.Upgrade);
+ return this.root;
+ }
+ }
+
+ public R UpgradeNoWait
+ {
+ get
+ {
+ SetLockMode(LockMode.UpgradeNoWait);
+ return this.root;
+ }
+ }
+
+ public R Write
+ {
+ get
+ {
+ SetLockMode(LockMode.Write);
+ return this.root;
+ }
+ }
+
+ }
+
+}
Copied: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs (from rev 4822, trunk/nhibernate/src/NHibernate/Criterion/QueryOverOrderBuilder.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -0,0 +1,72 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class QueryOverOrderBuilder<T> : QueryOverOrderBuilderBase<QueryOver<T>, T>
+ {
+
+ public QueryOverOrderBuilder(QueryOver<T> root, Expression<Func<T, object>> path) : base(root, path)
+ {}
+
+ public QueryOverOrderBuilder(QueryOver<T> root, Expression<Func<object>> path) : base(root, path)
+ {}
+
+ }
+
+ public class IQueryOverOrderBuilder<T> : QueryOverOrderBuilderBase<IQueryOver<T>, T>
+ {
+
+ public IQueryOverOrderBuilder(IQueryOver<T> root, Expression<Func<T, object>> path) : base(root, path)
+ {}
+
+ public IQueryOverOrderBuilder(IQueryOver<T> root, Expression<Func<object>> path) : base(root, path)
+ {}
+
+ }
+
+ public class QueryOverOrderBuilderBase<R, T> where R : IQueryOver<T>
+ {
+
+ protected R root;
+ protected LambdaExpression path;
+
+ protected QueryOverOrderBuilderBase(R root, Expression<Func<T, object>> path)
+ {
+ this.root = root;
+ this.path = path;
+ }
+
+ protected QueryOverOrderBuilderBase(R root, Expression<Func<object>> path)
+ {
+ this.root = root;
+ this.path = path;
+ }
+
+ public R Asc
+ {
+ get
+ {
+ this.root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, Order.Asc));
+ return this.root;
+ }
+ }
+
+ public R Desc
+ {
+ get
+ {
+ this.root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, Order.Desc));
+ return this.root;
+ }
+ }
+
+ }
+
+}
Copied: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs (from rev 4823, trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -0,0 +1,64 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class QueryOverSubqueryBuilder<T> : QueryOverSubqueryBuilderBase<QueryOver<T>, T, QueryOverSubqueryPropertyBuilder<T>>
+ {
+
+ public QueryOverSubqueryBuilder(QueryOver<T> root)
+ : base(root) { }
+
+ }
+
+ public class IQueryOverSubqueryBuilder<T> : QueryOverSubqueryBuilderBase<IQueryOver<T>, T, IQueryOverSubqueryPropertyBuilder<T>>
+ {
+
+ public IQueryOverSubqueryBuilder(IQueryOver<T> root)
+ : base(root) { }
+
+ }
+
+ public class QueryOverSubqueryBuilderBase<R, T, S>
+ where R : IQueryOver<T>
+ where S : QueryOverSubqueryPropertyBuilderBase, new()
+ {
+
+ protected R root;
+
+ protected QueryOverSubqueryBuilderBase(R root)
+ {
+ this.root = root;
+ }
+
+ /// <summary>
+ /// Subquery expression in the format
+ /// .Where(t => t.Property [==, !=, >, etc.] detachedQueryOver.As<propertyType>())
+ /// </summary>
+ public R Where(Expression<Func<T, bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery<T>(LambdaSubqueryType.Exact, expression);
+ root.And(criterion);
+ return root;
+ }
+
+ public S WhereProperty(Expression<Func<T, object>> expression)
+ {
+ string property = ExpressionProcessor.FindMemberExpression(expression.Body);
+ return (S)new S().Set(root, property, null);
+ }
+
+ public S WhereValue(object value)
+ {
+ return (S)new S().Set(root, null, value);
+ }
+
+ }
+
+}
Copied: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs (from rev 4823, trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryPropertyBuilder.cs)
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -0,0 +1,152 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class QueryOverSubqueryPropertyBuilder<T> : QueryOverSubqueryPropertyBuilderBase<QueryOver<T>, T>
+ {
+
+ public QueryOverSubqueryPropertyBuilder()
+ : base() { }
+
+ }
+
+ public class IQueryOverSubqueryPropertyBuilder<T> : QueryOverSubqueryPropertyBuilderBase<IQueryOver<T>, T>
+ {
+
+ public IQueryOverSubqueryPropertyBuilder()
+ : base() { }
+
+ }
+
+ public abstract class QueryOverSubqueryPropertyBuilderBase
+ {
+ protected QueryOverSubqueryPropertyBuilderBase() { }
+
+ internal abstract QueryOverSubqueryPropertyBuilderBase Set(object root, string path, object value);
+ }
+
+ public class QueryOverSubqueryPropertyBuilderBase<R, T> : QueryOverSubqueryPropertyBuilderBase
+ where R : IQueryOver<T>
+ {
+
+ protected R root;
+ protected string path;
+ protected object value;
+
+ protected QueryOverSubqueryPropertyBuilderBase()
+ {
+ }
+
+ internal override QueryOverSubqueryPropertyBuilderBase Set(object root, string path, object value)
+ {
+ this.root = (R)root;
+ this.path = path;
+ this.value = value;
+ return this;
+ }
+
+ private void AddSubquery<U>(
+ Func<string, DetachedCriteria, AbstractCriterion> propertyMethod,
+ Func<object, DetachedCriteria, AbstractCriterion> valueMethod,
+ QueryOver<U> detachedCriteria)
+ {
+ if (path != null)
+ {
+ root.And(propertyMethod(path, detachedCriteria.DetachedCriteria));
+ }
+ else
+ {
+ root.And(valueMethod(value, detachedCriteria.DetachedCriteria));
+ }
+ }
+
+ /// <summary>
+ /// Add a property equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Eq<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyEq, Subqueries.Eq, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property greater than or equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Ge<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyGe, Subqueries.Ge, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property greater than subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Gt<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyGt, Subqueries.Gt, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property in subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R In<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyIn, Subqueries.In, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property less than or equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Le<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyLe, Subqueries.Le, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property less than subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Lt<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyLt, Subqueries.Lt, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property not equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R Ne<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyNe, Subqueries.Ne, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property not in subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R NotIn<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyNotIn, Subqueries.NotIn, detachedCriteria);
+ return root;
+ }
+
+ }
+
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-08 10:58:42 UTC (rev 4824)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq.Expressions;
+using NHibernate.Criterion.Lambda;
using NHibernate.Impl;
using NHibernate.SqlCommand;
Deleted: trunk/nhibernate/src/NHibernate/Criterion/QueryOverFetchBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverFetchBuilder.cs 2009-11-08 10:58:42 UTC (rev 4824)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverFetchBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -1,69 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-
-using NHibernate.Impl;
-using NHibernate.SqlCommand;
-
-namespace NHibernate.Criterion
-{
-
- public class QueryOverFetchBuilder<T> : QueryOverFetchBuilderBase<QueryOver<T>, T>
- {
-
- public QueryOverFetchBuilder(QueryOver<T> root, Expression<Func<T, object>> path)
- : base(root, path) { }
-
- }
-
- public class IQueryOverFetchBuilder<T> : QueryOverFetchBuilderBase<IQueryOver<T>, T>
- {
-
- public IQueryOverFetchBuilder(IQueryOver<T> root, Expression<Func<T, object>> path)
- : base(root, path) { }
-
- }
-
- public class QueryOverFetchBuilderBase<R, T> where R : IQueryOver<T>
- {
-
- protected R root;
- protected string path;
-
- protected QueryOverFetchBuilderBase(R root, Expression<Func<T, object>> path)
- {
- this.root = root;
- this.path = ExpressionProcessor.FindMemberExpression(path.Body);
- }
-
- public R Eager
- {
- get
- {
- this.root.UnderlyingCriteria.SetFetchMode(path, FetchMode.Eager);
- return this.root;
- }
- }
-
- public R Lazy
- {
- get
- {
- this.root.UnderlyingCriteria.SetFetchMode(path, FetchMode.Lazy);
- return this.root;
- }
- }
-
- public R Default
- {
- get
- {
- this.root.UnderlyingCriteria.SetFetchMode(path, FetchMode.Default);
- return this.root;
- }
- }
-
- }
-
-}
Deleted: trunk/nhibernate/src/NHibernate/Criterion/QueryOverJoinBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverJoinBuilder.cs 2009-11-08 10:58:42 UTC (rev 4824)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverJoinBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -1,128 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-
-using NHibernate.Impl;
-using NHibernate.SqlCommand;
-
-namespace NHibernate.Criterion
-{
-
- public class QueryOverJoinBuilder<T> : QueryOverJoinBuilderBase<QueryOver<T>, T>
- {
- public QueryOverJoinBuilder(QueryOver<T> root, JoinType joinType) : base(root, joinType) { }
-
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path)
- {
- return root.JoinQueryOver<U>(path, joinType);
- }
-
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path)
- {
- return root.JoinQueryOver<U>(path, joinType);
- }
-
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path, Expression<Func<U>> alias)
- {
- return root.JoinQueryOver<U>(path, alias, joinType);
- }
-
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias)
- {
- return root.JoinQueryOver<U>(path, alias, joinType);
- }
-
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path)
- {
- return root.JoinQueryOver<U>(path, joinType);
- }
-
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path)
- {
- return root.JoinQueryOver<U>(path, joinType);
- }
-
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path, Expression<Func<U>> alias)
- {
- return root.JoinQueryOver<U>(path, alias, joinType);
- }
-
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias)
- {
- return root.JoinQueryOver<U>(path, alias, joinType);
- }
-
- }
-
- public class IQueryOverJoinBuilder<T> : QueryOverJoinBuilderBase<IQueryOver<T>, T>
- {
- public IQueryOverJoinBuilder(IQueryOver<T> root, JoinType joinType) : base(root, joinType) { }
-
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path)
- {
- return root.JoinQueryOver<U>(path, joinType);
- }
-
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path)
- {
- return root.JoinQueryOver<U>(path, joinType);
- }
-
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path, Expression<Func<U>> alias)
- {
- return root.JoinQueryOver<U>(path, alias, joinType);
- }
-
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias)
- {
- return root.JoinQueryOver<U>(path, alias, joinType);
- }
-
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path)
- {
- return root.JoinQueryOver<U>(path, joinType);
- }
-
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path)
- {
- return root.JoinQueryOver<U>(path, joinType);
- }
-
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path, Expression<Func<U>> alias)
- {
- return root.JoinQueryOver<U>(path, alias, joinType);
- }
-
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias)
- {
- return root.JoinQueryOver<U>(path, alias, joinType);
- }
-
- }
-
- public class QueryOverJoinBuilderBase<R, T> where R : IQueryOver<T>
- {
-
- protected R root;
- protected JoinType joinType;
-
- public QueryOverJoinBuilderBase(R root, JoinType joinType)
- {
- this.root = root;
- this.joinType = joinType;
- }
-
- public R JoinAlias(Expression<Func<T, object>> path, Expression<Func<object>> alias)
- {
- return (R)root.JoinAlias(path, alias, joinType);
- }
-
- public R JoinAlias(Expression<Func<object>> path, Expression<Func<object>> alias)
- {
- return (R)root.JoinAlias(path, alias, joinType);
- }
-
- }
-
-}
Deleted: trunk/nhibernate/src/NHibernate/Criterion/QueryOverLockBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverLockBuilder.cs 2009-11-08 10:58:42 UTC (rev 4824)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverLockBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -1,106 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-
-using NHibernate.Impl;
-using NHibernate.SqlCommand;
-
-namespace NHibernate.Criterion
-{
-
- public class QueryOverLockBuilder<T> : QueryOverLockBuilderBase<QueryOver<T>, T>
- {
-
- public QueryOverLockBuilder(QueryOver<T> root, Expression<Func<object>> alias)
- : base(root, alias) { }
-
- }
-
- public class IQueryOverLockBuilder<T> : QueryOverLockBuilderBase<IQueryOver<T>, T>
- {
-
- public IQueryOverLockBuilder(IQueryOver<T> root, Expression<Func<object>> alias)
- : base(root, alias) { }
-
- }
-
- public class QueryOverLockBuilderBase<R, T> where R : IQueryOver<T>
- {
-
- protected R root;
- protected string alias;
-
- protected QueryOverLockBuilderBase(R root, Expression<Func<object>> alias)
- {
- this.root = root;
-
- if (alias != null)
- this.alias = ExpressionProcessor.FindMemberExpression(alias.Body);
- }
-
- private void SetLockMode(LockMode lockMode)
- {
- if (alias != null)
- root.UnderlyingCriteria.SetLockMode(alias, lockMode);
- else
- root.UnderlyingCriteria.SetLockMode(lockMode);
- }
-
- public R Force
- {
- get
- {
- SetLockMode(LockMode.Force);
- return this.root;
- }
- }
-
- public R None
- {
- get
- {
- SetLockMode(LockMode.None);
- return this.root;
- }
- }
-
- public R Read
- {
- get
- {
- SetLockMode(LockMode.Read);
- return this.root;
- }
- }
-
- public R Upgrade
- {
- get
- {
- SetLockMode(LockMode.Upgrade);
- return this.root;
- }
- }
-
- public R UpgradeNoWait
- {
- get
- {
- SetLockMode(LockMode.UpgradeNoWait);
- return this.root;
- }
- }
-
- public R Write
- {
- get
- {
- SetLockMode(LockMode.Write);
- return this.root;
- }
- }
-
- }
-
-}
Deleted: trunk/nhibernate/src/NHibernate/Criterion/QueryOverOrderBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverOrderBuilder.cs 2009-11-08 10:58:42 UTC (rev 4824)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverOrderBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -1,72 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-
-using NHibernate.Impl;
-using NHibernate.SqlCommand;
-
-namespace NHibernate.Criterion
-{
-
- public class QueryOverOrderBuilder<T> : QueryOverOrderBuilderBase<QueryOver<T>, T>
- {
-
- public QueryOverOrderBuilder(QueryOver<T> root, Expression<Func<T, object>> path) : base(root, path)
- {}
-
- public QueryOverOrderBuilder(QueryOver<T> root, Expression<Func<object>> path) : base(root, path)
- {}
-
- }
-
- public class IQueryOverOrderBuilder<T> : QueryOverOrderBuilderBase<IQueryOver<T>, T>
- {
-
- public IQueryOverOrderBuilder(IQueryOver<T> root, Expression<Func<T, object>> path) : base(root, path)
- {}
-
- public IQueryOverOrderBuilder(IQueryOver<T> root, Expression<Func<object>> path) : base(root, path)
- {}
-
- }
-
- public class QueryOverOrderBuilderBase<R, T> where R : IQueryOver<T>
- {
-
- protected R root;
- protected LambdaExpression path;
-
- protected QueryOverOrderBuilderBase(R root, Expression<Func<T, object>> path)
- {
- this.root = root;
- this.path = path;
- }
-
- protected QueryOverOrderBuilderBase(R root, Expression<Func<object>> path)
- {
- this.root = root;
- this.path = path;
- }
-
- public R Asc
- {
- get
- {
- this.root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, Order.Asc));
- return this.root;
- }
- }
-
- public R Desc
- {
- get
- {
- this.root.UnderlyingCriteria.AddOrder(ExpressionProcessor.ProcessOrder(path, Order.Desc));
- return this.root;
- }
- }
-
- }
-
-}
Deleted: trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs 2009-11-08 10:58:42 UTC (rev 4824)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOverSubqueryBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
@@ -1,64 +0,0 @@
-
-using System;
-using System.Collections.Generic;
-using System.Linq.Expressions;
-
-using NHibernate.Impl;
-using NHibernate.SqlCommand;
-
-namespace NHibernate.Criterion
-{
-
- public class QueryOverSubqueryBuilder<T> : QueryOverSubqueryBuilderBase<QueryOver<T>, T, QueryOverSubqueryPropertyBuilder<T>>
- {
-
- public QueryOverSubqueryBuilder(QueryOver<T> root)
- : base(root) { }
-
- }
-
- public class IQueryOverSubqueryBuilder<T> : QueryOverSubqueryBuilderBase<IQueryOver<T>, T, IQueryOverSubqueryPropertyBuilder<T>>
- {
-
- public IQueryOverSubqueryBuilder(IQueryOver<T> root)
- : base(root) { }
-
- }
-
- public class QueryOverSubqueryBuilderBase<R, T, S>
- where R : IQueryOver<T>
- where S : QueryOverSubqueryPropertyBuilderBase, new()
- {
-
- protected R root;
-
- protected QueryOverSubqueryBuilderBase(R root)
- {
- this.root = root;
- }
-
- /// <summary>
- /// Subquery expression in the format
- /// .Where(t => t.Property [==, !=, >, etc.] detachedQueryOver.As<propertyType>())
- /// </summary>
- public R Where(Expression<Func<T, bool>> expression)
- {
- AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery<T>(LambdaSubqueryType.Exact, expression);
- root.And(criteri...
[truncated message content] |
|
From: <ste...@us...> - 2009-11-10 14:19:22
|
Revision: 4826
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4826&view=rev
Author: steverstrong
Date: 2009-11-10 14:19:09 +0000 (Tue, 10 Nov 2009)
Log Message:
-----------
Added more tests and support (in a semi-extensible way) for constructs such as string.ToUpper and datetime.Year
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs
trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Linq/AggregateTests.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Linq/Visitors/BaseHqlGeneratorForProperty.cs
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-10 13:32:28 UTC (rev 4825)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-10 14:19:09 UTC (rev 4826)
@@ -398,5 +398,10 @@
{
return new HqlExpressionList(_factory);
}
+
+ public HqlMethodCall MethodCall()
+ {
+ return new HqlMethodCall(_factory);
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-10 13:32:28 UTC (rev 4825)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-10 14:19:09 UTC (rev 4826)
@@ -147,6 +147,7 @@
return type.GetGenericArguments()[0];
}
+ // TODO - code duplicated in LinqExtensionMethods
private static bool IsNullableType(System.Type type)
{
return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>));
@@ -646,4 +647,11 @@
{
}
}
+
+ public class HqlMethodCall : HqlTreeNode
+ {
+ public HqlMethodCall(IASTFactory factory) : base(HqlSqlWalker.METHOD_CALL, "method", factory)
+ {
+ }
+ }
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs 2009-11-10 13:32:28 UTC (rev 4825)
+++ trunk/nhibernate/src/NHibernate/Linq/EnumerableHelper.cs 2009-11-10 14:19:09 UTC (rev 4826)
@@ -20,6 +20,11 @@
var methodInfo = ((MethodCallExpression)method.Body).Method;
return methodInfo.IsGenericMethod ? methodInfo.GetGenericMethodDefinition() : methodInfo;
}
+
+ public static MemberInfo GetProperty<TSource, TResult>(Expression<Func<TSource, TResult>> property)
+ {
+ return ((MemberExpression) property.Body).Member;
+ }
}
// TODO rename / remove - reflection helper above is better
Modified: trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2009-11-10 13:32:28 UTC (rev 4825)
+++ trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2009-11-10 14:19:09 UTC (rev 4826)
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
namespace NHibernate.Linq
@@ -17,5 +18,11 @@
method(item);
}
}
+
+ public static bool IsNullable(this System.Type type)
+ {
+ return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>));
+ }
+
}
}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Linq/Visitors/BaseHqlGeneratorForProperty.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/BaseHqlGeneratorForProperty.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/BaseHqlGeneratorForProperty.cs 2009-11-10 14:19:09 UTC (rev 4826)
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Reflection;
+
+namespace NHibernate.Linq.Visitors
+{
+ public abstract class BaseHqlGeneratorForProperty : IHqlGeneratorForProperty
+ {
+ public IEnumerable<MemberInfo> SupportedProperties { get; protected set; }
+ public abstract void BuildHql(MemberInfo member, Expression expression, HqlGeneratorExpressionTreeVisitor hqlGeneratorExpressionTreeVisitor);
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-10 13:32:28 UTC (rev 4825)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-10 14:19:09 UTC (rev 4826)
@@ -7,7 +7,6 @@
using NHibernate.Engine.Query;
using NHibernate.Hql.Ast;
using NHibernate.Linq.Expressions;
-using Remotion.Data.Linq;
using Remotion.Data.Linq.Clauses.Expressions;
using Remotion.Data.Linq.Clauses.ExpressionTreeVisitors;
@@ -206,16 +205,28 @@
protected override Expression VisitMemberExpression(MemberExpression expression)
{
+ // Strip out the .Value property of a nullable type, HQL doesn't need that
+ if (expression.Member.Name == "Value" && expression.Expression.Type.IsNullable())
+ {
+ VisitExpression(expression.Expression);
+ return expression;
+ }
+
+ // Look for "special" properties (DateTime.Month etc)
+ var generator = _methodGeneratorRegistry.GetPropertyGenerator(expression.Expression.Type, expression.Member);
+
+ if (generator != null)
+ {
+ generator.BuildHql(expression.Member, expression.Expression, this);
+ return expression;
+ }
+
+ // Else just emit standard HQL for a property reference
using (_stack.PushNode(_hqlTreeBuilder.Dot()))
{
- Expression newExpression = VisitExpression(expression.Expression);
+ VisitExpression(expression.Expression);
_stack.PushLeaf(_hqlTreeBuilder.Ident(expression.Member.Name));
-
- if (newExpression != expression.Expression)
- {
- return Expression.MakeMemberAccess(newExpression, expression.Member);
- }
}
return expression;
@@ -253,7 +264,7 @@
{
var generator = _methodGeneratorRegistry.GetMethodGenerator(expression.Method);
- generator.BuildHql(expression.Object, expression.Arguments, this);
+ generator.BuildHql(expression.Method, expression.Object, expression.Arguments, this);
return expression;
}
@@ -320,6 +331,12 @@
}
}
+ public interface IHqlGeneratorForProperty
+ {
+ IEnumerable<MemberInfo> SupportedProperties { get; }
+ void BuildHql(MemberInfo member, Expression expression, HqlGeneratorExpressionTreeVisitor hqlGeneratorExpressionTreeVisitor);
+ }
+
public class MethodGeneratorRegistry
{
public static MethodGeneratorRegistry Initialise()
@@ -329,11 +346,13 @@
// TODO - could use reflection here
registry.Register(new QueryableMethodsGenerator());
registry.Register(new StringMethodsGenerator());
+ registry.Register(new DateTimePropertyGenerator());
return registry;
}
private readonly Dictionary<MethodInfo, IHqlGeneratorForMethod> _registeredMethods = new Dictionary<MethodInfo, IHqlGeneratorForMethod>();
+ private readonly Dictionary<MemberInfo, IHqlGeneratorForProperty> _registeredProperties = new Dictionary<MemberInfo, IHqlGeneratorForProperty>();
public IHqlGeneratorForMethod GetMethodGenerator(MethodInfo method)
{
@@ -349,37 +368,55 @@
return methodGenerator;
}
- throw new NotSupportedException();
+ throw new NotSupportedException(method.ToString());
}
+ public IHqlGeneratorForProperty GetPropertyGenerator(System.Type type, MemberInfo member)
+ {
+ IHqlGeneratorForProperty propertyGenerator;
+
+ if (_registeredProperties.TryGetValue(member, out propertyGenerator))
+ {
+ return propertyGenerator;
+ }
+
+ // TODO - different usage pattern to method generator
+ return null;
+ }
+
public void RegisterMethodGenerator(MethodInfo method, IHqlGeneratorForMethod generator)
{
_registeredMethods.Add(method, generator);
}
+ public void RegisterPropertyGenerator(MemberInfo property, IHqlGeneratorForProperty generator)
+ {
+ _registeredProperties.Add(property, generator);
+ }
+
private void Register(IHqlGeneratorForType typeMethodGenerator)
{
- typeMethodGenerator.RegisterMethods(this);
+ typeMethodGenerator.Register(this);
}
-
}
public interface IHqlGeneratorForMethod
{
IEnumerable<MethodInfo> SupportedMethods { get; }
- void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor);
+ void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor);
}
public interface IHqlGeneratorForType
{
- void RegisterMethods(MethodGeneratorRegistry methodGeneratorRegistry);
+ void Register(MethodGeneratorRegistry methodGeneratorRegistry);
}
abstract public class BaseHqlGeneratorForType : IHqlGeneratorForType
{
protected readonly List<IHqlGeneratorForMethod> MethodRegistry = new List<IHqlGeneratorForMethod>();
+ protected readonly List<IHqlGeneratorForProperty> PropertyRegistry = new List<IHqlGeneratorForProperty>();
- public void RegisterMethods(MethodGeneratorRegistry methodGeneratorRegistry)
+ public void Register(MethodGeneratorRegistry methodGeneratorRegistry)
{
foreach (var generator in MethodRegistry)
{
@@ -388,6 +425,14 @@
methodGeneratorRegistry.RegisterMethodGenerator(method, generator);
}
}
+
+ foreach (var generator in PropertyRegistry)
+ {
+ foreach (var property in generator.SupportedProperties)
+ {
+ methodGeneratorRegistry.RegisterPropertyGenerator(property, generator);
+ }
+ }
}
}
@@ -395,9 +440,46 @@
{
public IEnumerable<MethodInfo> SupportedMethods { get; protected set; }
- public abstract void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor);
+ public abstract void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor);
}
+ public class DateTimePropertyGenerator : BaseHqlGeneratorForType
+ {
+ public DateTimePropertyGenerator()
+ {
+ PropertyRegistry.Add(new DatePartGenerator());
+ }
+
+ public class DatePartGenerator : BaseHqlGeneratorForProperty
+ {
+ public DatePartGenerator()
+ {
+ SupportedProperties = new[]
+ {
+ ReflectionHelper.GetProperty((DateTime x) => x.Year),
+ ReflectionHelper.GetProperty((DateTime x) => x.Month),
+ ReflectionHelper.GetProperty((DateTime x) => x.Day),
+ ReflectionHelper.GetProperty((DateTime x) => x.Hour),
+ ReflectionHelper.GetProperty((DateTime x) => x.Minute),
+ ReflectionHelper.GetProperty((DateTime x) => x.Second),
+ };
+ }
+
+ public override void BuildHql(MemberInfo member, Expression expression, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.MethodCall()))
+ {
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Ident(member.Name.ToLowerInvariant()));
+
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.ExpressionList()))
+ {
+ hqlVisitor.Visit(expression);
+ }
+ }
+ }
+ }
+ }
+
public class StringMethodsGenerator : BaseHqlGeneratorForType
{
public StringMethodsGenerator()
@@ -407,8 +489,32 @@
MethodRegistry.Add(new EndsWithGenerator());
MethodRegistry.Add(new ContainsGenerator());
MethodRegistry.Add(new EqualsGenerator());
+ MethodRegistry.Add(new ToUpperLowerGenerator());
+
+ PropertyRegistry.Add(new LengthGenerator());
}
+ public class LengthGenerator : BaseHqlGeneratorForProperty
+ {
+ public LengthGenerator()
+ {
+ SupportedProperties = new[] {ReflectionHelper.GetProperty((string x) => x.Length)};
+ }
+
+ public override void BuildHql(MemberInfo member, Expression expression, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.MethodCall()))
+ {
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Ident("length"));
+
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.ExpressionList()))
+ {
+ hqlVisitor.Visit(expression);
+ }
+ }
+ }
+ }
+
class StartsWithGenerator : BaseHqlGeneratorForMethod
{
public StartsWithGenerator()
@@ -416,7 +522,7 @@
SupportedMethods = new[] { ReflectionHelper.GetMethod<string>(x => x.StartsWith(null)) };
}
- public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ public override void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
{
using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Like()))
{
@@ -446,7 +552,7 @@
SupportedMethods = new[] { ReflectionHelper.GetMethod<string>(x => x.EndsWith(null)) };
}
- public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ public override void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
{
using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Like()))
{
@@ -476,7 +582,7 @@
SupportedMethods = new[] { ReflectionHelper.GetMethod<string>(x => x.Contains(null)) };
}
- public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ public override void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
{
using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Like()))
{
@@ -508,7 +614,7 @@
SupportedMethods = new[] { ReflectionHelper.GetMethod<string>(x => x.Equals((string)null)) };
}
- public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ public override void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
{
using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Equality()))
{
@@ -518,6 +624,40 @@
}
}
}
+
+ class ToUpperLowerGenerator : BaseHqlGeneratorForMethod
+ {
+ public ToUpperLowerGenerator()
+ {
+ SupportedMethods = new[]
+ {
+ ReflectionHelper.GetMethod<string>(x => x.ToUpper()),
+ ReflectionHelper.GetMethod<string>(x => x.ToUpperInvariant()),
+ ReflectionHelper.GetMethod<string>(x => x.ToLower()),
+ ReflectionHelper.GetMethod<string>(x => x.ToLowerInvariant())
+ };
+ }
+
+ public override void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ {
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.MethodCall()))
+ {
+ if (((method.Name == "ToUpper") || (method.Name == "ToUpperInvariant")))
+ {
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Ident("lower"));
+ }
+ else
+ {
+ hqlVisitor.Stack.PushLeaf(hqlVisitor.TreeBuilder.Ident("upper"));
+ }
+
+ using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.ExpressionList()))
+ {
+ hqlVisitor.Visit(targetObject);
+ }
+ }
+ }
+ }
}
public class QueryableMethodsGenerator : BaseHqlGeneratorForType
@@ -544,7 +684,7 @@
};
}
- public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ public override void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
{
// Any has one or two arguments. Arg 1 is the source and arg 2 is the optional predicate
using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Exists()))
@@ -590,7 +730,7 @@
};
}
- public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ public override void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
{
// All has two arguments. Arg 1 is the source and arg 2 is the predicate
using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Not()))
@@ -638,7 +778,7 @@
};
}
- public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ public override void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
{
using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Min()))
{
@@ -658,7 +798,7 @@
};
}
- public override void BuildHql(Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
+ public override void BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlGeneratorExpressionTreeVisitor hqlVisitor)
{
using (hqlVisitor.Stack.PushNode(hqlVisitor.TreeBuilder.Max()))
{
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-10 13:32:28 UTC (rev 4825)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-10 14:19:09 UTC (rev 4826)
@@ -585,6 +585,7 @@
<Compile Include="Linq\GroupJoin\GroupJoinSelectClauseRewriter.cs" />
<Compile Include="Linq\GroupJoin\LocateGroupJoinQuerySource.cs" />
<Compile Include="Linq\GroupJoin\NonAggregatingGroupJoinRewriter.cs" />
+ <Compile Include="Linq\Visitors\BaseHqlGeneratorForProperty.cs" />
<Compile Include="Linq\Visitors\SwapQuerySourceVisitor.cs" />
<Compile Include="Linq\Visitors\EqualityHqlGenerator.cs" />
<Compile Include="Linq\Visitors\ExpressionParameterVisitor.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/Linq/AggregateTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/AggregateTests.cs 2009-11-10 13:32:28 UTC (rev 4825)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/AggregateTests.cs 2009-11-10 14:19:09 UTC (rev 4826)
@@ -61,15 +61,14 @@
Console.WriteLine(query);
Assert.AreEqual("ALFKI,AROUT,", query.ToString());
}
- /*
- [Test]
- [Ignore("TODO")]
+
+ [Test]
public void AggregateWithMonthFunction()
{
var date = new DateTime(2007, 1, 1);
var query = (from e in db.Employees
- where db.Methods.Month(e.BirthDate) == date.Month
+ where e.BirthDate.Value.Month == date.Month
select e.FirstName)
.Aggregate(new StringBuilder(), (sb, name) => sb.Length > 0 ? sb.Append(", ").Append(name) : sb.Append(name));
@@ -77,15 +76,14 @@
Console.WriteLine(query);
}
- [Test]
- [Ignore("TODO")]
+ [Test]
public void AggregateWithBeforeYearFunction()
{
var date = new DateTime(1960, 1, 1);
var query = (from e in db.Employees
- where db.Methods.Year(e.BirthDate) < date.Year
- select db.Methods.Upper(e.FirstName))
+ where e.BirthDate.Value.Year < date.Year
+ select e.FirstName.ToUpper())
.Aggregate(new StringBuilder(), (sb, name) => sb.Length > 0 ? sb.Append(", ").Append(name) : sb.Append(name));
Console.WriteLine("Birthdays before {0}:", date.ToString("yyyy"));
@@ -93,13 +91,12 @@
}
[Test]
- [Ignore("TODO")]
public void AggregateWithOnOrAfterYearFunction()
{
var date = new DateTime(1960, 1, 1);
var query = (from e in db.Employees
- where db.Methods.Year(e.BirthDate) >= date.Year && db.Methods.Len(e.FirstName) > 4
+ where e.BirthDate.Value.Year >= date.Year && e.FirstName.Length > 4
select e.FirstName)
.Aggregate(new StringBuilder(), (sb, name) => sb.Length > 0 ? sb.Append(", ").Append(name) : sb.Append(name));
@@ -108,14 +105,13 @@
}
[Test]
- [Ignore("TODO")]
public void AggregateWithUpperAndLowerFunctions()
{
var date = new DateTime(2007, 1, 1);
var query = (from e in db.Employees
- where db.Methods.Month(e.BirthDate) == date.Month
- select new { First = e.FirstName.ToUpper(), Last = db.Methods.Lower(e.LastName) })
+ where e.BirthDate.Value.Month == date.Month
+ select new { First = e.FirstName.ToUpper(), Last = e.LastName.ToLower() })
.Aggregate(new StringBuilder(), (sb, name) => sb.Length > 0 ? sb.Append(", ").Append(name) : sb.Append(name));
Console.WriteLine("{0} Birthdays:", date.ToString("MMMM"));
@@ -123,17 +119,19 @@
}
[Test]
- [Ignore("TODO")]
+ [Ignore("TODO: Custom functions")]
public void AggregateWithCustomFunction()
{
+ /*
var date = new DateTime(1960, 1, 1);
var query = (from e in db.Employees
- where db.Methods.Year(e.BirthDate) < date.Year
+ where e.BirthDate.Value.Year < date.Year
select db.Methods.fnEncrypt(e.FirstName))
.Aggregate(new StringBuilder(), (sb, name) => sb.AppendLine(BitConverter.ToString(name)));
Console.WriteLine(query);
- }*/
+ */
+ }
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-10 18:07:33
|
Revision: 4827
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4827&view=rev
Author: ricbrown
Date: 2009-11-10 18:07:01 +0000 (Tue, 10 Nov 2009)
Log Message:
-----------
Added remaining (inline) QueryOver subquery overloads.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs 2009-11-10 14:19:09 UTC (rev 4826)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs 2009-11-10 18:07:01 UTC (rev 4827)
@@ -38,6 +38,24 @@
}
/// <summary>
+ /// Add an Exists subquery criterion
+ /// </summary>
+ public R WhereExists<U>(QueryOver<U> detachedQuery)
+ {
+ root.And(Subqueries.Exists(detachedQuery.DetachedCriteria));
+ return root;
+ }
+
+ /// <summary>
+ /// Add a NotExists subquery criterion
+ /// </summary>
+ public R WhereNotExists<U>(QueryOver<U> detachedQuery)
+ {
+ root.And(Subqueries.NotExists(detachedQuery.DetachedCriteria));
+ return root;
+ }
+
+ /// <summary>
/// Subquery expression in the format
/// .Where(t => t.Property [==, !=, >, etc.] detachedQueryOver.As<propertyType>())
/// </summary>
@@ -48,12 +66,73 @@
return root;
}
+ /// <summary>
+ /// Subquery expression in the format
+ /// .Where(() => alias.Property [==, !=, >, etc.] detachedQueryOver.As<propertyType>())
+ /// </summary>
+ public R Where(Expression<Func<bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery(LambdaSubqueryType.Exact, expression);
+ root.And(criterion);
+ return root;
+ }
+
+ /// <summary>
+ /// Subquery expression in the format
+ /// .WhereAll(t => t.Property [==, !=, >, etc.] detachedQueryOver.As<propertyType>())
+ /// </summary>
+ public R WhereAll(Expression<Func<T, bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery<T>(LambdaSubqueryType.All, expression);
+ root.And(criterion);
+ return root;
+ }
+
+ /// <summary>
+ /// Subquery expression in the format
+ /// .WhereAll(() => alias.Property [==, !=, >, etc.] detachedQueryOver.As<propertyType>())
+ /// </summary>
+ public R WhereAll(Expression<Func<bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery(LambdaSubqueryType.All, expression);
+ root.And(criterion);
+ return root;
+ }
+
+ /// <summary>
+ /// Subquery expression in the format
+ /// .WhereSome(t => t.Property [==, !=, >, etc.] detachedQueryOver.As<propertyType>())
+ /// </summary>
+ public R WhereSome(Expression<Func<T, bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery<T>(LambdaSubqueryType.Some, expression);
+ root.And(criterion);
+ return root;
+ }
+
+ /// <summary>
+ /// Subquery expression in the format
+ /// .WhereSome(() => alias.Property [==, !=, >, etc.] detachedQueryOver.As<propertyType>())
+ /// </summary>
+ public R WhereSome(Expression<Func<bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery(LambdaSubqueryType.Some, expression);
+ root.And(criterion);
+ return root;
+ }
+
public S WhereProperty(Expression<Func<T, object>> expression)
{
string property = ExpressionProcessor.FindMemberExpression(expression.Body);
return (S)new S().Set(root, property, null);
}
+ public S WhereProperty(Expression<Func<object>> expression)
+ {
+ string property = ExpressionProcessor.FindMemberExpression(expression.Body);
+ return (S)new S().Set(root, property, null);
+ }
+
public S WhereValue(object value)
{
return (S)new S().Set(root, null, value);
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs 2009-11-10 14:19:09 UTC (rev 4826)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs 2009-11-10 18:07:01 UTC (rev 4827)
@@ -78,6 +78,16 @@
}
/// <summary>
+ /// Add a property equal all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R EqAll<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyEqAll, Subqueries.EqAll, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
/// Create a property greater than or equal subquery criterion
/// </summary>
/// <param name="detachedCriteria">detached subquery</param>
@@ -88,6 +98,26 @@
}
/// <summary>
+ /// Create a property greater than or equal all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R GeAll<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyGeAll, Subqueries.GeAll, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property greater than or equal some subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R GeSome<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyGeSome, Subqueries.GeSome, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
/// Create a property greater than subquery criterion
/// </summary>
/// <param name="detachedCriteria">detached subquery</param>
@@ -98,6 +128,26 @@
}
/// <summary>
+ /// Create a property greater than all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R GtAll<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyGtAll, Subqueries.GtAll, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property greater than some subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R GtSome<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyGtSome, Subqueries.GtSome, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
/// Create a property in subquery criterion
/// </summary>
/// <param name="detachedCriteria">detached subquery</param>
@@ -118,6 +168,26 @@
}
/// <summary>
+ /// Create a property less than or equal all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R LeAll<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyLeAll, Subqueries.LeAll, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property less than or equal some subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R LeSome<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyLeSome, Subqueries.LeSome, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
/// Create a property less than subquery criterion
/// </summary>
/// <param name="detachedCriteria">detached subquery</param>
@@ -128,6 +198,26 @@
}
/// <summary>
+ /// Create a property less than all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R LtAll<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyLtAll, Subqueries.LtAll, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
+ /// Create a property less than some subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public R LtSome<U>(QueryOver<U> detachedCriteria)
+ {
+ AddSubquery(Subqueries.PropertyLtSome, Subqueries.LtSome, detachedCriteria);
+ return root;
+ }
+
+ /// <summary>
/// Create a property not equal subquery criterion
/// </summary>
/// <param name="detachedCriteria">detached subquery</param>
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-10 14:19:09 UTC (rev 4826)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-10 18:07:01 UTC (rev 4827)
@@ -103,6 +103,63 @@
}
[Test]
+ public void PropertyAlias()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Subqueries.PropertyEq("personAlias.Name", DetachedCriteriaName));
+
+ Person personAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .WithSubquery.WhereProperty(() => personAlias.Name).Eq(DetachedQueryOverName);
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
+ public void PropertyAll()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyEqAll("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyGeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGtAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtAll("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.WhereProperty(p => p.Name).EqAll(DetachedQueryOverName)
+ .WithSubquery.WhereProperty(p => p.Age).GeAll(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Age).GtAll(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Age).LeAll(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Age).LtAll(DetachedQueryOverAge);
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
+ public void PropertySome()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyGeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGtSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtSome("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.WhereProperty(p => p.Age).GeSome(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Age).GtSome(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Age).LeSome(DetachedQueryOverAge)
+ .WithSubquery.WhereProperty(p => p.Age).LtSome(DetachedQueryOverAge);
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void PropertyAsSyntax()
{
ICriteria expected =
@@ -127,6 +184,67 @@
}
[Test]
+ public void PropertyAsSyntaxAlias()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Subqueries.PropertyEq("personAlias.Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyGtSome("personAlias.Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtAll("personAlias.Age", DetachedCriteriaAge));
+
+ Person personAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .WithSubquery.Where(() => personAlias.Name == DetachedQueryOverName.As<string>())
+ .WithSubquery.WhereSome(() => personAlias.Age > DetachedQueryOverAge.As<int>())
+ .WithSubquery.WhereAll(() => personAlias.Age < DetachedQueryOverAge.As<int>());
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
+ public void PropertyAsAllSyntax()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyEqAll("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyGeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGtAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtAll("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.WhereAll(p => p.Name == DetachedQueryOverName.As<string>())
+ .WithSubquery.WhereAll(p => p.Age >= DetachedQueryOverAge.As<int>())
+ .WithSubquery.WhereAll(p => p.Age > DetachedQueryOverAge.As<int>())
+ .WithSubquery.WhereAll(p => p.Age <= DetachedQueryOverAge.As<int>())
+ .WithSubquery.WhereAll(p => p.Age < DetachedQueryOverAge.As<int>());
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
+ public void PropertyAsSomeSyntax()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyGeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGtSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtSome("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.WhereSome(p => p.Age >= DetachedQueryOverAge.As<int>())
+ .WithSubquery.WhereSome(p => p.Age > DetachedQueryOverAge.As<int>())
+ .WithSubquery.WhereSome(p => p.Age <= DetachedQueryOverAge.As<int>())
+ .WithSubquery.WhereSome(p => p.Age < DetachedQueryOverAge.As<int>());
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void Value()
{
ICriteria expected =
@@ -154,6 +272,64 @@
AssertCriteriaAreEqual(expected, actual);
}
+ [Test]
+ public void ValueAll()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.EqAll("Name", DetachedCriteriaName))
+ .Add(Subqueries.GeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.GtAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.LeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.LtAll("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.WhereValue("Name").EqAll(DetachedQueryOverName)
+ .WithSubquery.WhereValue("Age").GeAll(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Age").GtAll(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Age").LeAll(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Age").LtAll(DetachedQueryOverAge);
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
+ public void ValueSome()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.GeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.GtSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.LeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.LtSome("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.WhereValue("Age").GeSome(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Age").GtSome(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Age").LeSome(DetachedQueryOverAge)
+ .WithSubquery.WhereValue("Age").LtSome(DetachedQueryOverAge);
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
+ public void UntypedSubqueries()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.Exists(DetachedCriteriaChild))
+ .Add(Subqueries.NotExists(DetachedCriteriaChild));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .WithSubquery.WhereExists(DetachedQueryOverChild)
+ .WithSubquery.WhereNotExists(DetachedQueryOverChild);
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ste...@us...> - 2009-11-11 13:37:59
|
Revision: 4828
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4828&view=rev
Author: steverstrong
Date: 2009-11-11 13:37:38 +0000 (Wed, 11 Nov 2009)
Log Message:
-----------
More Linq tests and improvement to the Hql tree generation code
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ConstructorNode.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/HqlSqlWalkerTreeAdapter.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/EqualityHqlGenerator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ProjectionEvaluator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Northwind.cs
trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Linq/Functions/
trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForMethod.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForProperty.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/BaseHqlGeneratorForType.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/DateTimeGenerator.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/FunctionRegistry.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForMethod.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForProperty.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/IHqlGeneratorForType.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/QueryableGenerator.cs
trunk/nhibernate/src/NHibernate/Linq/Functions/StringGenerator.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/IHqlExpressionVisitor.cs
trunk/nhibernate/src/NHibernate.Test/Linq/BinaryBooleanExpressionTests.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Animal.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/AnotherEntity.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Role.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/Timesheet.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/User.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Entities/UserComponent.cs
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/Animal.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/AnotherEntity.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/Role.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/TimeSheet.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Linq/Mappings/User.hbm.xml
Removed Paths:
-------------
trunk/nhibernate/src/NHibernate/Linq/HqlNodeStack.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/BaseHqlGeneratorForProperty.cs
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ASTNode.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -17,11 +17,6 @@
private readonly IToken _token;
private List<IASTNode> _children;
- // TODO - currently just used for Constructor stuff in Linq. Should really have a subtype,
- // and a new TreeFactory thingy for the Linq AST generator. But for now...
- private object _hack;
- public object Hack { get { return _hack; } set { _hack = value; } }
-
public ASTNode()
: this((IToken)null) {}
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ConstructorNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ConstructorNode.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/ConstructorNode.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -109,16 +109,7 @@
}
else
{
- if (Hack != null && Hack is ConstructorInfo)
- {
- // The Linq parser has the constructor information available, so it can pass it straight through.
- // Currently using nasty Hack property :) This *will* be improved!
- _constructor = (ConstructorInfo)Hack;
- }
- else
- {
- _constructor = ResolveConstructor(path);
- }
+ _constructor = ResolveConstructor(path);
}
}
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/HqlSqlWalkerTreeAdapter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/HqlSqlWalkerTreeAdapter.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/HqlSqlWalkerTreeAdapter.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -176,15 +176,6 @@
{
var dupped = (IASTNode) Create(node.Token);
- // TODO - nasty hack for Linq. To be removed :). In general, should this just call the copy
- // constructor or something? Then this may work for derived classes... (via a Create overload...)
- ASTNode x = dupped as ASTNode;
- ASTNode y = node as ASTNode;
- if (x != null && y != null)
- {
- x.Hack = y.Hack;
- }
-
dupped.Parent = node.Parent;
return dupped;
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Reflection;
using NHibernate.Hql.Ast.ANTLR.Tree;
namespace NHibernate.Hql.Ast
@@ -70,11 +69,6 @@
return new HqlRange(_factory, ident);
}
- public HqlRange Range()
- {
- return new HqlRange(_factory);
- }
-
public HqlRange Range(HqlTreeNode ident, HqlAlias alias)
{
return new HqlRange(_factory, ident, alias);
@@ -95,49 +89,44 @@
return new HqlAlias(_factory, alias);
}
- public HqlEquality Equality()
+ public HqlEquality Equality(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlEquality(_factory);
- }
-
- public HqlEquality Equality(HqlTreeNode lhs, HqlTreeNode rhs)
- {
return new HqlEquality(_factory, lhs, rhs);
}
- public HqlBooleanAnd BooleanAnd()
+ public HqlBooleanAnd BooleanAnd(HqlBooleanExpression lhs, HqlBooleanExpression rhs)
{
- return new HqlBooleanAnd(_factory);
+ return new HqlBooleanAnd(_factory, lhs, rhs);
}
- public HqlBooleanOr BooleanOr()
+ public HqlBooleanOr BooleanOr(HqlBooleanExpression lhs, HqlBooleanExpression rhs)
{
- return new HqlBooleanOr(_factory);
+ return new HqlBooleanOr(_factory, lhs, rhs);
}
- public HqlAdd Add()
+ public HqlAdd Add(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlAdd(_factory);
+ return new HqlAdd(_factory, lhs, rhs);
}
- public HqlSubtract Subtract()
+ public HqlSubtract Subtract(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlSubtract(_factory);
+ return new HqlSubtract(_factory, lhs, rhs);
}
- public HqlMultiplty Multiply()
+ public HqlMultiplty Multiply(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlMultiplty(_factory);
+ return new HqlMultiplty(_factory, lhs, rhs);
}
- public HqlDivide Divide()
+ public HqlDivide Divide(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlDivide(_factory);
+ return new HqlDivide(_factory, lhs, rhs);
}
- public HqlDot Dot()
+ public HqlDot Dot(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlDot(_factory);
+ return new HqlDot(_factory, lhs, rhs);
}
public HqlParameter Parameter(string name)
@@ -145,16 +134,11 @@
return new HqlParameter(_factory, name);
}
- public HqlWhere Where(HqlTreeNode expression)
+ public HqlWhere Where(HqlExpression expression)
{
return new HqlWhere(_factory, expression);
}
- public HqlWhere Where()
- {
- return new HqlWhere(_factory);
- }
-
// TODO - constant will be removed when we have parameter handling done properly. Particularly bad datetime handling here, so it'll be good to delete it :)
public HqlConstant Constant(object value)
{
@@ -194,82 +178,72 @@
return new HqlOrderBy(_factory);
}
- public HqlOrderBy OrderBy(HqlTreeNode expression, HqlDirection hqlDirection)
+ public HqlSelect Select(HqlExpression expression)
{
- return new HqlOrderBy(_factory, expression, hqlDirection);
- }
-
- public HqlSelect Select(HqlTreeNode expression)
- {
return new HqlSelect(_factory, expression);
}
- public HqlSelect Select(params HqlTreeNode[] expression)
+ public HqlSelect Select(params HqlExpression[] expression)
{
return new HqlSelect(_factory, expression);
}
- public HqlSelect Select(IEnumerable<HqlTreeNode> expressions)
+ public HqlSelect Select(IEnumerable<HqlExpression> expressions)
{
return new HqlSelect(_factory, expressions.ToArray());
}
- public HqlConstructor Constructor(ConstructorInfo constructor)
+ public HqlCase Case(HqlWhen[] whenClauses)
{
- return new HqlConstructor(_factory, constructor);
+ return new HqlCase(_factory, whenClauses, null);
}
- public HqlNill Holder()
+ public HqlCase Case(HqlWhen[] whenClauses, HqlExpression ifFalse)
{
- return new HqlNill(_factory);
+ return new HqlCase(_factory, whenClauses, ifFalse);
}
- public HqlCase Case()
+ public HqlWhen When(HqlExpression predicate, HqlExpression ifTrue)
{
- return new HqlCase(_factory);
+ return new HqlWhen(_factory, predicate, ifTrue);
}
- public HqlWhen When()
+ public HqlElse Else(HqlExpression ifFalse)
{
- return new HqlWhen(_factory);
+ return new HqlElse(_factory, ifFalse);
}
- public HqlElse Else()
+ public HqlInequality Inequality(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlElse(_factory);
+ return new HqlInequality(_factory, lhs, rhs);
}
- public HqlInequality Inequality()
+ public HqlLessThan LessThan(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlInequality(_factory);
+ return new HqlLessThan(_factory, lhs, rhs);
}
- public HqlLessThan LessThan()
+ public HqlLessThanOrEqual LessThanOrEqual(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlLessThan(_factory);
+ return new HqlLessThanOrEqual(_factory, lhs, rhs);
}
- public HqlLessThanOrEqual LessThanOrEqual()
+ public HqlGreaterThan GreaterThan(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlLessThanOrEqual(_factory);
+ return new HqlGreaterThan(_factory, lhs, rhs);
}
- public HqlGreaterThan GreaterThan()
+ public HqlGreaterThanOrEqual GreaterThanOrEqual(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlGreaterThan(_factory);
+ return new HqlGreaterThanOrEqual(_factory, lhs, rhs);
}
- public HqlGreaterThanOrEqual GreaterThanOrEqual()
- {
- return new HqlGreaterThanOrEqual(_factory);
- }
-
public HqlCount Count()
{
return new HqlCount(_factory);
}
- public HqlCount Count(HqlTreeNode child)
+ public HqlCount Count(HqlExpression child)
{
return new HqlCount(_factory, child);
}
@@ -279,7 +253,7 @@
return new HqlRowStar(_factory);
}
- public HqlCast Cast(HqlTreeNode expression, System.Type type)
+ public HqlCast Cast(HqlExpression expression, System.Type type)
{
return new HqlCast(_factory, expression, type);
}
@@ -289,58 +263,33 @@
return new HqlBitwiseNot(_factory);
}
- public HqlNot Not()
+ public HqlNot Not(HqlBooleanExpression operand)
{
- return new HqlNot(_factory);
+ return new HqlNot(_factory, operand);
}
- public HqlAverage Average()
+ public HqlAverage Average(HqlExpression expression)
{
- return new HqlAverage(_factory);
- }
-
- public HqlAverage Average(HqlTreeNode expression)
- {
return new HqlAverage(_factory, expression);
}
- public HqlSum Sum()
+ public HqlSum Sum(HqlExpression expression)
{
- return new HqlSum(_factory);
- }
-
- public HqlSum Sum(HqlTreeNode expression)
- {
return new HqlSum(_factory, expression);
}
- public HqlMin Min()
+ public HqlMin Min(HqlExpression expression)
{
- return new HqlMin(_factory);
- }
-
- public HqlMin Min(HqlTreeNode expression)
- {
return new HqlMin(_factory, expression);
}
- public HqlMax Max()
+ public HqlMax Max(HqlExpression expression)
{
- return new HqlMax(_factory);
- }
-
- public HqlMax Max(HqlTreeNode expression)
- {
return new HqlMax(_factory, expression);
}
- public HqlAnd And(HqlTreeNode left, HqlTreeNode right)
+ public HqlJoin Join(HqlExpression expression, HqlAlias @alias)
{
- return new HqlAnd(_factory, left, right);
- }
-
- public HqlJoin Join(HqlTreeNode expression, HqlAlias @alias)
- {
return new HqlJoin(_factory, expression, @alias);
}
@@ -349,9 +298,9 @@
return new HqlAny(_factory);
}
- public HqlExists Exists()
+ public HqlExists Exists(HqlQuery query)
{
- return new HqlExists(_factory);
+ return new HqlExists(_factory, query);
}
public HqlElements Elements()
@@ -374,9 +323,9 @@
return new HqlDirectionDescending(_factory);
}
- public HqlGroupBy GroupBy()
+ public HqlGroupBy GroupBy(HqlExpression expression)
{
- return new HqlGroupBy(_factory);
+ return new HqlGroupBy(_factory, expression);
}
public HqlAll All()
@@ -384,14 +333,14 @@
return new HqlAll(_factory);
}
- public HqlLike Like()
+ public HqlLike Like(HqlExpression lhs, HqlExpression rhs)
{
- return new HqlLike(_factory);
+ return new HqlLike(_factory, lhs, rhs);
}
- public HqlConcat Concat()
+ public HqlConcat Concat(params HqlExpression[] args)
{
- return new HqlConcat(_factory);
+ return new HqlConcat(_factory, args);
}
public HqlExpressionList ExpressionList()
@@ -399,9 +348,14 @@
return new HqlExpressionList(_factory);
}
- public HqlMethodCall MethodCall()
+ public HqlMethodCall MethodCall(string methodName, HqlExpression parameter)
{
- return new HqlMethodCall(_factory);
+ return new HqlMethodCall(_factory, methodName, parameter);
}
+
+ public HqlDistinctHolder DistinctHolder(params HqlTreeNode[] children)
+ {
+ return new HqlDistinctHolder(_factory, children);
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-10 18:07:01 UTC (rev 4827)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-11 13:37:38 UTC (rev 4828)
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Reflection;
using NHibernate.Hql.Ast.ANTLR;
using NHibernate.Hql.Ast.ANTLR.Tree;
@@ -8,18 +7,37 @@
{
public class HqlTreeNode
{
- protected readonly IASTNode _node;
- protected readonly List<HqlTreeNode> _children;
+ private readonly IASTNode _node;
+ private readonly List<HqlTreeNode> _children;
- protected HqlTreeNode(int type, string text, IASTFactory factory, params HqlTreeNode[] children)
+ protected HqlTreeNode(int type, string text, IASTFactory factory, IEnumerable<HqlTreeNode> children)
{
_node = factory.CreateNode(type, text);
_children = new List<HqlTreeNode>();
+ AddChildren(children);
+ }
+
+ protected HqlTreeNode(int type, string text, IASTFactory factory, params HqlTreeNode[] children) : this(type, text, factory, (IEnumerable<HqlTreeNode>) children)
+ {
+ }
+
+ private void AddChildren(IEnumerable<HqlTreeNode> children)
+ {
foreach (var child in children)
{
- _children.Add(child);
- _node.AddChild(child.AstNode);
+ if (child != null)
+ {
+ if (child is HqlDistinctHolder)
+ {
+ AddChildren(child.Children);
+ }
+ else
+ {
+ _children.Add(child);
+ _node.AddChild(child.AstNode);
+ }
+ }
}
}
@@ -57,13 +75,7 @@
public IEnumerable<HqlTreeNode> Children
{
- get
- {
- foreach (var child in _children)
- {
- yield return child;
- }
- }
+ get { return _children; }
}
public void ClearChildren()
@@ -72,6 +84,11 @@
_node.ClearChildren();
}
+ protected void SetText(string text)
+ {
+ _node.Text = text;
+ }
+
internal IASTNode AstNode
{
get { return _node; }
@@ -79,28 +96,74 @@
internal void AddChild(HqlTreeNode child)
{
- _children.Add(child);
- _node.AddChild(child.AstNode);
+ if (child is HqlDistinctHolder)
+ {
+ AddChildren(child.Children);
+ }
+ else
+ {
+ _children.Add(child);
+ _node.AddChild(child.AstNode);
+ }
}
- public void AddChild(int index, HqlTreeNode node)
+ public HqlExpression AsExpression()
{
- _children.Insert(index, node);
- _node.InsertChild(index, node.AstNode);
+ // TODO - nice error handling if cast fails
+ return (HqlExpression) this;
}
+ public virtual HqlBooleanExpression AsBooleanExpression()
+ {
+ // TODO - nice error handling if cast fails
+ return (HqlBooleanExpression)this;
+ }
}
- public class HqlQuery : HqlTreeNode
+ public abstract class HqlStatement : HqlTreeNode
{
- internal HqlQuery(IASTFactory factory, params HqlTreeNode[] children)
+ protected HqlStatement(int type, string text, IASTFactory factory, params HqlTreeNode[] children)
+ : base(type, text, factory, children)
+ {
+ }
+ }
+
+ public abstract class HqlExpression : HqlTreeNode
+ {
+ protected HqlExpression(int type, string text, IASTFactory factory, IEnumerable<HqlTreeNode> children)
+ : base(type, text, factory, children)
+ {
+ }
+
+ protected HqlExpression(int type, string text, IASTFactory factory, params HqlTreeNode[] children)
+ : base(type, text, factory, children)
+ {
+ }
+ }
+
+ public abstract class HqlBooleanExpression : HqlExpression
+ {
+ protected HqlBooleanExpression(int type, string text, IASTFactory factory, IEnumerable<HqlTreeNode> children)
+ : base(type, text, factory, children)
+ {
+ }
+
+ protected HqlBooleanExpression(int type, string text, IASTFactory factory, params HqlTreeNode[] children)
+ : base(type, text, factory, children)
+ {
+ }
+ }
+
+ public class HqlQuery : HqlExpression
+ {
+ internal HqlQuery(IASTFactory factory, params HqlStatement[] children)
: base(HqlSqlWalker.QUERY, "query", factory, children)
{
}
}
- public class HqlIdent : HqlTreeNode
+ public class HqlIdent : HqlExpression
{
internal HqlIdent(IASTFactory factory, string ident)
: base(HqlSqlWalker.IDENT, ident, factory)
@@ -118,24 +181,24 @@
switch (System.Type.GetTypeCode(type))
{
case TypeCode.Boolean:
- _node.Text = "bool";
+ SetText("bool");
break;
case TypeCode.Int32:
- _node.Text = "integer";
+ SetText("integer");
break;
case TypeCode.Decimal:
- _node.Text = "decimal";
+ SetText("decimal");
break;
case TypeCode.DateTime:
- _node.Text = "datetime";
+ SetText("datetime");
break;
case TypeCode.String:
- _node.Text = "string";
+ SetText("string");
break;
default:
if (type == typeof(Guid))
{
- _node.Text = "guid";
+ SetText("guid");
break;
}
throw new NotSupportedException(string.Format("Don't currently support idents of type {0}", type.Name));
@@ -155,7 +218,7 @@
}
- public class HqlRange : HqlTreeNode
+ public class HqlRange : HqlStatement
{
internal HqlRange(IASTFactory factory, params HqlTreeNode[] children)
: base(HqlSqlWalker.RANGE, "range", factory, children)
@@ -163,7 +226,7 @@
}
}
- public class HqlFrom : HqlTreeNode
+ public class HqlFrom : HqlStatement
{
internal HqlFrom(IASTFactory factory, params HqlTreeNode[] children)
: base(HqlSqlWalker.FROM, "from", factory, children)
@@ -171,7 +234,7 @@
}
}
- public class HqlSelectFrom : HqlTreeNode
+ public class HqlSelectFrom : HqlStatement
{
internal HqlSelectFrom(IASTFactory factory, params HqlTreeNode[] children)
: base(HqlSqlWalker.SELECT_FROM, "select_from", factory, children)
@@ -179,7 +242,7 @@
}
}
- public class HqlAlias : HqlTreeNode
+ public class HqlAlias : HqlExpression
{
public HqlAlias(IASTFactory factory, string @alias)
: base(HqlSqlWalker.ALIAS, alias, factory)
@@ -187,68 +250,63 @@
}
}
- public class HqlDivide : HqlTreeNode
+ public class HqlDivide : HqlExpression
{
- public HqlDivide(IASTFactory factory)
- : base(HqlSqlWalker.DIV, "/", factory)
+ public HqlDivide(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.DIV, "/", factory, lhs, rhs)
{
}
}
- public class HqlMultiplty : HqlTreeNode
+ public class HqlMultiplty : HqlExpression
{
- public HqlMultiplty(IASTFactory factory)
- : base(HqlSqlWalker.STAR, "*", factory)
+ public HqlMultiplty(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.STAR, "*", factory, lhs, rhs)
{
}
}
- public class HqlSubtract : HqlTreeNode
+ public class HqlSubtract : HqlExpression
{
- public HqlSubtract(IASTFactory factory)
- : base(HqlSqlWalker.MINUS, "-", factory)
+ public HqlSubtract(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.MINUS, "-", factory, lhs, rhs)
{
}
}
- public class HqlAdd : HqlTreeNode
+ public class HqlAdd : HqlExpression
{
- public HqlAdd(IASTFactory factory)
- : base(HqlSqlWalker.PLUS, "+", factory)
+ public HqlAdd(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.PLUS, "+", factory, lhs, rhs)
{
}
}
- public class HqlBooleanOr : HqlTreeNode
+ public class HqlBooleanOr : HqlBooleanExpression
{
- public HqlBooleanOr(IASTFactory factory)
- : base(HqlSqlWalker.OR, "or", factory)
+ public HqlBooleanOr(IASTFactory factory, HqlBooleanExpression lhs, HqlBooleanExpression rhs)
+ : base(HqlSqlWalker.OR, "or", factory, lhs, rhs)
{
}
}
- public class HqlBooleanAnd : HqlTreeNode
+ public class HqlBooleanAnd : HqlBooleanExpression
{
- public HqlBooleanAnd(IASTFactory factory)
- : base(HqlSqlWalker.AND, "/", factory)
+ public HqlBooleanAnd(IASTFactory factory, HqlBooleanExpression lhs, HqlBooleanExpression rhs)
+ : base(HqlSqlWalker.AND, "/", factory, lhs, rhs)
{
}
}
- public class HqlEquality : HqlTreeNode
+ public class HqlEquality : HqlBooleanExpression
{
- public HqlEquality(IASTFactory factory)
- : base(HqlSqlWalker.EQ, "==", factory)
- {
- }
-
- public HqlEquality(IASTFactory factory, HqlTreeNode lhs, HqlTreeNode rhs)
+ public HqlEquality(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
: base(HqlSqlWalker.EQ, "==", factory, lhs, rhs)
{
}
}
- public class HqlParameter : HqlTreeNode
+ public class HqlParameter : HqlExpression
{
public HqlParameter(IASTFactory factory, string name)
: base(HqlSqlWalker.COLON, ":", factory)
@@ -257,28 +315,40 @@
}
}
- public class HqlDot : HqlTreeNode
+ public class HqlDot : HqlExpression
{
- public HqlDot(IASTFactory factory)
- : base(HqlSqlWalker.DOT, ".", factory)
+ private readonly IASTFactory _factory;
+
+ public HqlDot(IASTFactory factory, HqlExpression lhs, HqlExpression rhs)
+ : base(HqlSqlWalker.DOT, ".", factory, lhs, rhs)
{
+ _factory = factory;
}
+
+ public override HqlBooleanExpression AsBooleanExpression()
+ {
+ // If we are of boolean type, then we can acts as boolean expression
+ // TODO - implement type check
+ return new HqlBooleanDot(_factory, this);
+ }
}
- public class HqlWhere : HqlTreeNode
+ public class HqlBooleanDot : HqlBooleanExpression
{
- public HqlWhere(IASTFactory factory)
- : base(HqlSqlWalker.WHERE, "where", factory)
+ public HqlBooleanDot(IASTFactory factory, HqlDot dot) : base(dot.AstNode.Type, dot.AstNode.Text, factory, dot.Children)
{
}
+ }
- public HqlWhere(IASTFactory factory, HqlTreeNode expression)
+ public class HqlWhere : HqlStatement
+ {
+ public HqlWhere(IASTFactory factory, HqlExpression expression)
: base(HqlSqlWalker.WHERE, "where", factory, expression)
{
}
}
- public class HqlConstant : HqlTreeNode
+ public class HqlConstant : HqlExpression
{
public HqlConstant(IASTFactory factory, int type, string value)
: base(type, value, factory)
@@ -334,19 +404,12 @@
}
}
- public class HqlOrderBy : HqlTreeNode
+ public class HqlOrderBy : HqlStatement
{
public HqlOrderBy(IASTFactory factory)
: base(HqlSqlWalker.ORDER, "", factory)
{
}
-
- public HqlOrderBy(IASTFactory factory, HqlTreeNode expression, HqlDirection hqlDirection)
- : base(HqlSqlWalker.ORDER, "", factory, expression,
- hqlDirection == HqlDirection.Ascending ?
- (HqlTreeNode)new HqlDirectionAscending(factory) : (HqlTreeNode)new HqlDirectionDescending(factory))
- {
- }
}
public enum HqlDirection
@@ -355,7 +418,7 @@
Descending
}
- public class HqlDirectionAscending : HqlTreeNode
+ public class HqlDirectionAscending : HqlStatement
{
public HqlDirectionAscending(IASTFactory factory)
: base(HqlSqlWalker.ASCENDING, "asc", factory)
@@ -363,7 +426,7 @@
}
}
- public class HqlDirectionDescending : HqlTreeNode
+ public class HqlDirectionDescending : HqlStatement
{
public HqlDirectionDescending(IASTFactory factory)
: base(HqlSqlWalker.DESCENDING, "desc", factory)
@@ -371,120 +434,107 @@
}
}
- public class HqlSelect : HqlTreeNode
+ public class HqlSelect : HqlStatement
{
- public HqlSelect(IASTFact...
[truncated message content] |
|
From: <ric...@us...> - 2009-11-18 13:13:32
|
Revision: 4833
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4833&view=rev
Author: ricbrown
Date: 2009-11-18 12:29:32 +0000 (Wed, 18 Nov 2009)
Log Message:
-----------
Added extra support for nullable bool and enum to QueryOver.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs
Modified: trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2009-11-15 15:39:52 UTC (rev 4832)
+++ trunk/nhibernate/src/NHibernate/Impl/ExpressionProcessor.cs 2009-11-18 12:29:32 UTC (rev 4833)
@@ -124,6 +124,13 @@
if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess
|| memberExpression.Expression.NodeType == ExpressionType.Call)
{
+ if (IsNullableOfT(memberExpression.Member.DeclaringType))
+ {
+ // it's a Nullable<T>, so ignore any .Value
+ if (memberExpression.Member.Name == "Value")
+ return FindMemberExpression(memberExpression.Expression);
+ }
+
return FindMemberExpression(memberExpression.Expression) + "." + memberExpression.Member.Name;
}
else
@@ -258,6 +265,9 @@
if (type.IsAssignableFrom(value.GetType()))
return value;
+ if (IsNullableOfT(type))
+ type = Nullable.GetUnderlyingType(type);
+
if (type.IsEnum)
return Enum.ToObject(type, value);
@@ -267,6 +277,12 @@
throw new Exception("Cannot convert '" + value.ToString() + "' to " + type.ToString());
}
+ private static bool IsNullableOfT(System.Type type)
+ {
+ return type.IsGenericType
+ && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
+ }
+
private static ICriterion ProcessSimpleExpression(BinaryExpression be)
{
string property = FindMemberExpression(be.Left);
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2009-11-15 15:39:52 UTC (rev 4832)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ExpressionProcessorFixture.cs 2009-11-18 12:29:32 UTC (rev 4833)
@@ -116,6 +116,38 @@
}
}
+ [Test]
+ public void TestEvaluateNullableIntExpression()
+ {
+ ICriterion before = Restrictions.Eq("NullableAge", 5);
+ ICriterion after = ExpressionProcessor.ProcessExpression<Person>(p => p.NullableAge == 5);
+ Assert.AreEqual(before.ToString(), after.ToString());
+ }
+
+ [Test]
+ public void TestEvaluateNullableEnumExpression()
+ {
+ ICriterion before = Restrictions.Eq("NullableGender", PersonGender.Female);
+ ICriterion after = ExpressionProcessor.ProcessExpression<Person>(p => p.NullableGender == PersonGender.Female);
+ Assert.AreEqual(before.ToString(), after.ToString());
+ }
+
+ [Test]
+ public void TestEvaluateNullableEnumValueExpression()
+ {
+ ICriterion before = Restrictions.Eq("NullableGender", PersonGender.Female);
+ ICriterion after = ExpressionProcessor.ProcessExpression<Person>(p => p.NullableGender.Value == PersonGender.Female);
+ Assert.AreEqual(before.ToString(), after.ToString());
+ }
+
+ [Test]
+ public void TestEvaluateNullableBoolExpression()
+ {
+ ICriterion before = Restrictions.Eq("NullableIsParent", true);
+ ICriterion after = ExpressionProcessor.ProcessExpression<Person>(p => p.NullableIsParent.Value);
+ Assert.AreEqual(before.ToString(), after.ToString());
+ }
+
}
}
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2009-11-15 15:39:52 UTC (rev 4832)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs 2009-11-18 12:29:32 UTC (rev 4833)
@@ -25,6 +25,10 @@
public virtual bool IsParent { get; set; }
public virtual char Blood { get; set; }
+ public virtual int? NullableAge { get; set; }
+ public virtual PersonGender? NullableGender { get; set; }
+ public virtual bool? NullableIsParent { get; set; }
+
public virtual IEnumerable<Child> Children { get; set; }
public virtual IList<Person> PersonList { get; set; }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-18 15:17:28
|
Revision: 4834
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4834&view=rev
Author: ricbrown
Date: 2009-11-18 15:17:20 +0000 (Wed, 18 Nov 2009)
Log Message:
-----------
Added Subqueries overloads to create ICriterion for QueryOver.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaSubqueryBuilder.cs
Added: trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaSubqueryBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaSubqueryBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaSubqueryBuilder.cs 2009-11-18 15:17:20 UTC (rev 4834)
@@ -0,0 +1,195 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class LambdaSubqueryBuilder
+ {
+ private string propertyName;
+ private object value;
+
+ /// <summary>
+ /// Constructed with property name
+ /// </summary>
+ public LambdaSubqueryBuilder(string propertyName, object value)
+ {
+ this.propertyName = propertyName;
+ this.value = value;
+ }
+
+ private AbstractCriterion CreatePropertyCriterion<U>( Func<string, DetachedCriteria, AbstractCriterion> propertyFactoryMethod,
+ Func<object, DetachedCriteria, AbstractCriterion> valueFactoryMethod,
+ QueryOver<U> detachedCriteria)
+ {
+ if (propertyName != null)
+ {
+ return propertyFactoryMethod(propertyName, detachedCriteria.DetachedCriteria);
+ }
+ else
+ {
+ return valueFactoryMethod(value, detachedCriteria.DetachedCriteria);
+ }
+ }
+
+ /// <summary>
+ /// Add a property equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion Eq<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyEq, Subqueries.Eq, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Add a property equal all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion EqAll<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyEqAll, Subqueries.EqAll, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property greater than or equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion Ge<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyGe, Subqueries.Ge, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property greater than or equal all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion GeAll<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyGeAll, Subqueries.GeAll, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property greater than or equal some subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion GeSome<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyGeSome, Subqueries.GeSome, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property greater than subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion Gt<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyGt, Subqueries.Gt, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property greater than all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion GtAll<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyGtAll, Subqueries.GtAll, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property greater than some subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion GtSome<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyGtSome, Subqueries.GtSome, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property in subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion In<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyIn, Subqueries.In, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property less than or equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion Le<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyLe, Subqueries.Le, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property less than or equal all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion LeAll<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyLeAll, Subqueries.LeAll, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property less than or equal some subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion LeSome<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyLeSome, Subqueries.LeSome, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property less than subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion Lt<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyLt, Subqueries.Lt, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property less than all subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion LtAll<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyLtAll, Subqueries.LtAll, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property less than some subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion LtSome<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyLtSome, Subqueries.LtSome, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property not equal subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion Ne<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyNe, Subqueries.Ne, detachedCriteria);
+ }
+
+ /// <summary>
+ /// Create a property not in subquery criterion
+ /// </summary>
+ /// <param name="detachedCriteria">detached subquery</param>
+ public AbstractCriterion NotIn<U>(QueryOver<U> detachedCriteria)
+ {
+ return CreatePropertyCriterion(Subqueries.PropertyNotIn, Subqueries.NotIn, detachedCriteria);
+ }
+
+ }
+
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs 2009-11-18 12:29:32 UTC (rev 4833)
+++ trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs 2009-11-18 15:17:20 UTC (rev 4834)
@@ -1,5 +1,9 @@
using System;
+using System.Linq.Expressions;
+using NHibernate.Criterion.Lambda;
+using NHibernate.Impl;
+
namespace NHibernate.Criterion
{
/// <summary>
@@ -195,5 +199,124 @@
{
return new SelectSubqueryExpression(detachedCriteria);
}
+
+ /// <summary>
+ /// Create a ICriterion for the specified property subquery expression
+ /// </summary>
+ /// <typeparam name="T">generic type</typeparam>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>returns LambdaSubqueryBuilder</returns>
+ public static LambdaSubqueryBuilder WhereProperty<T>(Expression<Func<T, object>> expression)
+ {
+ string property = ExpressionProcessor.FindMemberExpression(expression.Body);
+ return new LambdaSubqueryBuilder(property, null);
+ }
+
+ /// <summary>
+ /// Create a ICriterion for the specified property subquery expression
+ /// </summary>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>returns LambdaSubqueryBuilder</returns>
+ public static LambdaSubqueryBuilder WhereProperty(Expression<Func<object>> expression)
+ {
+ string property = ExpressionProcessor.FindMemberExpression(expression.Body);
+ return new LambdaSubqueryBuilder(property, null);
+ }
+
+ /// <summary>
+ /// Create a ICriterion for the specified value subquery expression
+ /// </summary>
+ /// <param name="value">value</param>
+ /// <returns>returns LambdaSubqueryBuilder</returns>
+ public static LambdaSubqueryBuilder WhereValue(object value)
+ {
+ return new LambdaSubqueryBuilder(null, value);
+ }
+
+ /// <summary>
+ /// Create ICriterion for subquery expression using lambda syntax
+ /// </summary>
+ /// <typeparam name="T">type of property</typeparam>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>NHibernate.ICriterion.AbstractCriterion</returns>
+ public static AbstractCriterion Where<T>(Expression<Func<T, bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery<T>(LambdaSubqueryType.Exact, expression);
+ return criterion;
+ }
+
+ /// <summary>
+ /// Create ICriterion for (exact) subquery expression using lambda syntax
+ /// </summary>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>NHibernate.ICriterion.AbstractCriterion</returns>
+ public static AbstractCriterion Where(Expression<Func<bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery(LambdaSubqueryType.Exact, expression);
+ return criterion;
+ }
+
+ /// <summary>
+ /// Create ICriterion for (all) subquery expression using lambda syntax
+ /// </summary>
+ /// <typeparam name="T">type of property</typeparam>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>NHibernate.ICriterion.AbstractCriterion</returns>
+ public static AbstractCriterion WhereAll<T>(Expression<Func<T, bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery<T>(LambdaSubqueryType.All, expression);
+ return criterion;
+ }
+
+ /// <summary>
+ /// Create ICriterion for (all) subquery expression using lambda syntax
+ /// </summary>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>NHibernate.ICriterion.AbstractCriterion</returns>
+ public static AbstractCriterion WhereAll(Expression<Func<bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery(LambdaSubqueryType.All, expression);
+ return criterion;
+ }
+
+ /// <summary>
+ /// Create ICriterion for (some) subquery expression using lambda syntax
+ /// </summary>
+ /// <typeparam name="T">type of property</typeparam>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>NHibernate.ICriterion.AbstractCriterion</returns>
+ public static AbstractCriterion WhereSome<T>(Expression<Func<T, bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery<T>(LambdaSubqueryType.Some, expression);
+ return criterion;
+ }
+
+ /// <summary>
+ /// Create ICriterion for (some) subquery expression using lambda syntax
+ /// </summary>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>NHibernate.ICriterion.AbstractCriterion</returns>
+ public static AbstractCriterion WhereSome(Expression<Func<bool>> expression)
+ {
+ AbstractCriterion criterion = ExpressionProcessor.ProcessSubquery(LambdaSubqueryType.Some, expression);
+ return criterion;
+ }
+
+ /// <summary>
+ /// Add an Exists subquery criterion
+ /// </summary>
+ public static AbstractCriterion WhereExists<U>(QueryOver<U> detachedQuery)
+ {
+ return Subqueries.Exists(detachedQuery.DetachedCriteria);
+ }
+
+ /// <summary>
+ /// Add a NotExists subquery criterion
+ /// </summary>
+ public static AbstractCriterion WhereNotExists<U>(QueryOver<U> detachedQuery)
+ {
+ return Subqueries.NotExists(detachedQuery.DetachedCriteria);
+ }
+
}
}
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-18 12:29:32 UTC (rev 4833)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-18 15:17:20 UTC (rev 4834)
@@ -505,6 +505,7 @@
<Compile Include="Context\WcfOperationSessionContext.cs" />
<Compile Include="Criterion\GroupedProjection.cs" />
<Compile Include="Criterion\IPropertyProjection.cs" />
+ <Compile Include="Criterion\Lambda\LambdaSubqueryBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverFetchBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverJoinBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverLockBuilder.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-18 12:29:32 UTC (rev 4833)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-18 15:17:20 UTC (rev 4834)
@@ -103,6 +103,34 @@
}
[Test]
+ public void PropertyCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyGe("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGt("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyIn("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyLe("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLt("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyNe("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyNotIn("Name", DetachedCriteriaName));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.WhereProperty<Person>(p => p.Name).Eq(DetachedQueryOverName))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).Ge(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).Gt(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Name).In(DetachedQueryOverName))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).Le(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).Lt(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Name).Ne(DetachedQueryOverName))
+ .And(Subqueries.WhereProperty<Person>(p => p.Name).NotIn(DetachedQueryOverName));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void PropertyAlias()
{
ICriteria expected =
@@ -118,6 +146,21 @@
}
[Test]
+ public void PropertyAliasCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Subqueries.PropertyEq("personAlias.Name", DetachedCriteriaName));
+
+ Person personAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .And(Subqueries.WhereProperty(() => personAlias.Name).Eq(DetachedQueryOverName));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void PropertyAll()
{
ICriteria expected =
@@ -140,6 +183,28 @@
}
[Test]
+ public void PropertyAllCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyEqAll("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyGeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGtAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtAll("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.WhereProperty<Person>(p => p.Name).EqAll(DetachedQueryOverName))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).GeAll(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).GtAll(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).LeAll(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).LtAll(DetachedQueryOverAge));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void PropertySome()
{
ICriteria expected =
@@ -160,6 +225,26 @@
}
[Test]
+ public void PropertySomeCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyGeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGtSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtSome("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).GeSome(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).GtSome(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).LeSome(DetachedQueryOverAge))
+ .And(Subqueries.WhereProperty<Person>(p => p.Age).LtSome(DetachedQueryOverAge));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void PropertyAsSyntax()
{
ICriteria expected =
@@ -184,6 +269,20 @@
}
[Test]
+ public void PropertyAsSyntaxCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.Where<Person>(p => p.Name == DetachedQueryOverName.As<string>()));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void PropertyAsSyntaxAlias()
{
ICriteria expected =
@@ -203,6 +302,25 @@
}
[Test]
+ public void PropertyAsSyntaxAliasCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Subqueries.PropertyEq("personAlias.Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyGtSome("personAlias.Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtAll("personAlias.Age", DetachedCriteriaAge));
+
+ Person personAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .And(Subqueries.Where(() => personAlias.Name == DetachedQueryOverName.As<string>()))
+ .And(Subqueries.WhereSome(() => personAlias.Age > DetachedQueryOverAge.As<int>()))
+ .And(Subqueries.WhereAll(() => personAlias.Age < DetachedQueryOverAge.As<int>()));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void PropertyAsAllSyntax()
{
ICriteria expected =
@@ -225,6 +343,28 @@
}
[Test]
+ public void PropertyAsAllSyntaxCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyEqAll("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyGeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGtAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtAll("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.WhereAll<Person>(p => p.Name == DetachedQueryOverName.As<string>()))
+ .And(Subqueries.WhereAll<Person>(p => p.Age >= DetachedQueryOverAge.As<int>()))
+ .And(Subqueries.WhereAll<Person>(p => p.Age > DetachedQueryOverAge.As<int>()))
+ .And(Subqueries.WhereAll<Person>(p => p.Age <= DetachedQueryOverAge.As<int>()))
+ .And(Subqueries.WhereAll<Person>(p => p.Age < DetachedQueryOverAge.As<int>()));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void PropertyAsSomeSyntax()
{
ICriteria expected =
@@ -245,6 +385,26 @@
}
[Test]
+ public void PropertyAsSomeSyntaxCrtierion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.PropertyGeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyGtSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.PropertyLtSome("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.WhereSome<Person>(p => p.Age >= DetachedQueryOverAge.As<int>()))
+ .And(Subqueries.WhereSome<Person>(p => p.Age > DetachedQueryOverAge.As<int>()))
+ .And(Subqueries.WhereSome<Person>(p => p.Age <= DetachedQueryOverAge.As<int>()))
+ .And(Subqueries.WhereSome<Person>(p => p.Age < DetachedQueryOverAge.As<int>()));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void Value()
{
ICriteria expected =
@@ -273,6 +433,34 @@
}
[Test]
+ public void ValueCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.Eq("Name", DetachedCriteriaName))
+ .Add(Subqueries.Ge("Age", DetachedCriteriaAge))
+ .Add(Subqueries.Gt("Age", DetachedCriteriaAge))
+ .Add(Subqueries.In("Name", DetachedCriteriaName))
+ .Add(Subqueries.Le("Age", DetachedCriteriaAge))
+ .Add(Subqueries.Lt("Age", DetachedCriteriaAge))
+ .Add(Subqueries.Ne("Name", DetachedCriteriaName))
+ .Add(Subqueries.NotIn("Name", DetachedCriteriaName));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.WhereValue("Name").Eq(DetachedQueryOverName))
+ .And(Subqueries.WhereValue("Age").Ge(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Age").Gt(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Name").In(DetachedQueryOverName))
+ .And(Subqueries.WhereValue("Age").Le(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Age").Lt(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Name").Ne(DetachedQueryOverName))
+ .And(Subqueries.WhereValue("Name").NotIn(DetachedQueryOverName));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void ValueAll()
{
ICriteria expected =
@@ -295,6 +483,28 @@
}
[Test]
+ public void ValueAllCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.EqAll("Name", DetachedCriteriaName))
+ .Add(Subqueries.GeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.GtAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.LeAll("Age", DetachedCriteriaAge))
+ .Add(Subqueries.LtAll("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.WhereValue("Name").EqAll(DetachedQueryOverName))
+ .And(Subqueries.WhereValue("Age").GeAll(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Age").GtAll(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Age").LeAll(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Age").LtAll(DetachedQueryOverAge));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void ValueSome()
{
ICriteria expected =
@@ -315,6 +525,26 @@
}
[Test]
+ public void ValueSomeCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.GeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.GtSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.LeSome("Age", DetachedCriteriaAge))
+ .Add(Subqueries.LtSome("Age", DetachedCriteriaAge));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.WhereValue("Age").GeSome(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Age").GtSome(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Age").LeSome(DetachedQueryOverAge))
+ .And(Subqueries.WhereValue("Age").LtSome(DetachedQueryOverAge));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void UntypedSubqueries()
{
ICriteria expected =
@@ -330,6 +560,22 @@
AssertCriteriaAreEqual(expected, actual);
}
+ [Test]
+ public void UntypedSubqueriesCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person))
+ .Add(Subqueries.Exists(DetachedCriteriaChild))
+ .Add(Subqueries.NotExists(DetachedCriteriaChild));
+
+ var actual =
+ CreateTestQueryOver<Person>()
+ .And(Subqueries.WhereExists(DetachedQueryOverChild))
+ .And(Subqueries.WhereNotExists(DetachedQueryOverChild));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-19 10:05:25
|
Revision: 4835
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4835&view=rev
Author: ricbrown
Date: 2009-11-19 10:05:05 +0000 (Thu, 19 Nov 2009)
Log Message:
-----------
Added arbitrary ICriterion creation from Lambda expression.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2009-11-18 15:17:20 UTC (rev 4834)
+++ trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2009-11-19 10:05:05 UTC (rev 4835)
@@ -1,5 +1,8 @@
+using System;
using System.Collections;
using System.Collections.Generic;
+using System.Linq.Expressions;
+using NHibernate.Impl;
namespace NHibernate.Criterion
{
@@ -731,5 +734,29 @@
{
return new NaturalIdentifier();
}
+
+ /// <summary>
+ /// Create an ICriterion for the supplied LambdaExpression
+ /// </summary>
+ /// <typeparam name="T">generic type</typeparam>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>return NHibernate.Criterion.ICriterion</returns>
+ public static ICriterion Where<T>(Expression<Func<T, bool>> expression)
+ {
+ ICriterion criterion = ExpressionProcessor.ProcessExpression<T>(expression);
+ return criterion;
+ }
+
+ /// <summary>
+ /// Create an ICriterion for the supplied LambdaExpression
+ /// </summary>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>return NHibernate.Criterion.ICriterion</returns>
+ public static ICriterion Where(Expression<Func<bool>> expression)
+ {
+ ICriterion criterion = ExpressionProcessor.ProcessExpression(expression);
+ return criterion;
+ }
+
}
}
Added: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-19 10:05:05 UTC (rev 4835)
@@ -0,0 +1,34 @@
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+using NHibernate.Criterion;
+
+namespace NHibernate.Test.Criteria.Lambda
+{
+
+ [TestFixture]
+ public class RestrictionsFixture : LambdaFixtureBase
+ {
+
+ [Test]
+ public void ArbitraryCriterion()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Restrictions.Lt("Age", 65))
+ .Add(Restrictions.Ge("personAlias.Age", 18));
+
+ Person personAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .Where(Restrictions.Where<Person>(p => p.Age < 65))
+ .And(Restrictions.Where(() => personAlias.Age >= 18));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ }
+
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-18 15:17:20 UTC (rev 4834)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-19 10:05:05 UTC (rev 4835)
@@ -164,6 +164,7 @@
<Compile Include="Criteria\Lambda\IntegrationFixture.cs" />
<Compile Include="Criteria\Lambda\LambdaFixtureBase.cs" />
<Compile Include="Criteria\Lambda\Model.cs" />
+ <Compile Include="Criteria\Lambda\RestrictionsFixture.cs" />
<Compile Include="Criteria\Lambda\SubqueryFixture.cs" />
<Compile Include="Criteria\MaterialResource.cs" />
<Compile Include="Criteria\ProjectionsTest.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-19 11:15:19
|
Revision: 4836
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4836&view=rev
Author: ricbrown
Date: 2009-11-19 11:15:09 +0000 (Thu, 19 Nov 2009)
Log Message:
-----------
Added missing modifier on QueryOver.WithSubquery.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-19 10:05:05 UTC (rev 4835)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-19 11:15:09 UTC (rev 4836)
@@ -171,7 +171,7 @@
return this;
}
- QueryOverSubqueryBuilder<T> WithSubquery
+ public QueryOverSubqueryBuilder<T> WithSubquery
{
get { return new QueryOverSubqueryBuilder<T>(this); }
}
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-19 10:05:05 UTC (rev 4835)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-19 11:15:09 UTC (rev 4836)
@@ -103,6 +103,23 @@
}
[Test]
+ public void DetachedSubquery()
+ {
+ DetachedCriteria expected =
+ DetachedCriteria.For<Person>("personAlias")
+ .Add(Subqueries.PropertyEq("Name", DetachedCriteriaName))
+ .Add(Subqueries.PropertyEq("personAlias.Name", DetachedCriteriaName));
+
+ Person personAlias = null;
+ QueryOver<Person> actual =
+ new QueryOver<Person>(() => personAlias)
+ .WithSubquery.WhereProperty(p => p.Name).Eq(DetachedQueryOverName)
+ .WithSubquery.WhereProperty(() => personAlias.Name).Eq(DetachedQueryOverName);
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void PropertyCriterion()
{
ICriteria expected =
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-19 12:31:29
|
Revision: 4837
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4837&view=rev
Author: ricbrown
Date: 2009-11-19 12:31:20 +0000 (Thu, 19 Nov 2009)
Log Message:
-----------
Added more Restrictions overloads for lambda expressions.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs
Added: trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs 2009-11-19 12:31:20 UTC (rev 4837)
@@ -0,0 +1,123 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class LambdaRestrictionBuilder
+ {
+ public class LambdaBetweenBuilder
+ {
+ private string propertyName;
+ private object lo;
+
+ public LambdaBetweenBuilder(string propertyName, object lo)
+ {
+ this.propertyName = propertyName;
+ this.lo = lo;
+ }
+
+ public AbstractCriterion And(object hi)
+ {
+ return Restrictions.Between(propertyName, lo, hi);
+ }
+ }
+
+ private string propertyName;
+
+ /// <summary>
+ /// Constructed with property name
+ /// </summary>
+ public LambdaRestrictionBuilder(string propertyName)
+ {
+ this.propertyName = propertyName;
+ }
+
+ /// <summary>
+ /// Apply a "between" constraint to the named property
+ /// </summary>
+ public LambdaBetweenBuilder IsBetween(object lo)
+ {
+ return new LambdaBetweenBuilder(propertyName, lo);
+ }
+
+ /// <summary>
+ /// A case-insensitive "like", similar to Postgres "ilike" operator
+ /// </summary>
+ public AbstractCriterion IsInsensitiveLike(object value)
+ {
+ return Restrictions.InsensitiveLike(propertyName, value);
+ }
+
+ /// <summary>
+ /// A case-insensitive "like", similar to Postgres "ilike" operator
+ /// </summary>
+ public AbstractCriterion IsInsensitiveLike(string value, MatchMode matchMode)
+ {
+ return Restrictions.InsensitiveLike(propertyName, value, matchMode);
+ }
+
+ /// <summary>
+ /// Apply an "is empty" constraint to the named property
+ /// </summary>
+ public AbstractEmptinessExpression IsEmpty
+ {
+ get { return Restrictions.IsEmpty(propertyName); }
+ }
+
+ /// <summary>
+ /// Apply a "not is empty" constraint to the named property
+ /// </summary>
+ public AbstractEmptinessExpression IsNotEmpty
+ {
+ get { return Restrictions.IsNotEmpty(propertyName); }
+ }
+
+ /// <summary>
+ /// Apply an "is null" constraint to the named property
+ /// </summary>
+ public AbstractCriterion IsNull
+ {
+ get { return Restrictions.IsNull(propertyName); }
+ }
+
+ /// <summary>
+ /// Apply an "not is null" constraint to the named property
+ /// </summary>
+ public AbstractCriterion IsNotNull
+ {
+ get { return Restrictions.IsNotNull(propertyName); }
+ }
+
+ /// <summary>
+ /// Apply a "like" constraint to the named property
+ /// </summary>
+ public SimpleExpression IsLike(object value)
+ {
+ return Restrictions.Like(propertyName, value);
+ }
+
+ /// <summary>
+ /// Apply a "like" constraint to the named property
+ /// </summary>
+ public SimpleExpression IsLike(string value, MatchMode matchMode)
+ {
+ return Restrictions.Like(propertyName, value, matchMode);
+ }
+
+ /// <summary>
+ /// Apply a "like" constraint to the named property
+ /// </summary>
+ public AbstractCriterion IsLike(string value, MatchMode matchMode, char? escapeChar)
+ {
+ return Restrictions.Like(propertyName, value, matchMode, escapeChar);
+ }
+
+ }
+
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2009-11-19 11:15:09 UTC (rev 4836)
+++ trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2009-11-19 12:31:20 UTC (rev 4837)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
+using NHibernate.Criterion.Lambda;
using NHibernate.Impl;
namespace NHibernate.Criterion
@@ -758,5 +759,27 @@
return criterion;
}
+ /// <summary>
+ /// Build an ICriterion for the given property
+ /// </summary>
+ /// <param name="expression">lambda expression identifying property</param>
+ /// <returns>returns LambdaRestrictionBuilder</returns>
+ public static LambdaRestrictionBuilder WhereProperty<T>(Expression<Func<T, object>> expression)
+ {
+ string property = ExpressionProcessor.FindMemberExpression(expression.Body);
+ return new LambdaRestrictionBuilder(property);
+ }
+
+ /// <summary>
+ /// Build an ICriterion for the given property
+ /// </summary>
+ /// <param name="expression">lambda expression identifying property</param>
+ /// <returns>returns LambdaRestrictionBuilder</returns>
+ public static LambdaRestrictionBuilder WhereProperty(Expression<Func<object>> expression)
+ {
+ string property = ExpressionProcessor.FindMemberExpression(expression.Body);
+ return new LambdaRestrictionBuilder(property);
+ }
+
}
}
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-19 11:15:09 UTC (rev 4836)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-19 12:31:20 UTC (rev 4837)
@@ -505,6 +505,7 @@
<Compile Include="Context\WcfOperationSessionContext.cs" />
<Compile Include="Criterion\GroupedProjection.cs" />
<Compile Include="Criterion\IPropertyProjection.cs" />
+ <Compile Include="Criterion\Lambda\LambdaRestrictionBuilder.cs" />
<Compile Include="Criterion\Lambda\LambdaSubqueryBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverFetchBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverJoinBuilder.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-19 11:15:09 UTC (rev 4836)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-19 12:31:20 UTC (rev 4837)
@@ -29,6 +29,41 @@
AssertCriteriaAreEqual(expected, actual);
}
+ [Test]
+ public void SqlFunctions()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Restrictions.Between("Age", 18, 65))
+ .Add(Restrictions.Between("personAlias.Age", 18, 65))
+ .Add(Restrictions.InsensitiveLike("Name", "test"))
+ .Add(Restrictions.InsensitiveLike("Name", "tEsT", MatchMode.Anywhere))
+ .Add(Restrictions.IsEmpty("Children"))
+ .Add(Restrictions.IsNotEmpty("Children"))
+ .Add(Restrictions.IsNotNull("Name"))
+ .Add(Restrictions.IsNull("Name"))
+ .Add(Restrictions.Like("Name", "%test%"))
+ .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere))
+ .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere, '?'));
+
+ Person personAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .Where(Restrictions.WhereProperty<Person>(p => p.Age).IsBetween(18).And(65))
+ .And(Restrictions.WhereProperty(() => personAlias.Age).IsBetween(18).And(65))
+ .And(Restrictions.WhereProperty<Person>(p => p.Name).IsInsensitiveLike("test"))
+ .And(Restrictions.WhereProperty<Person>(p => p.Name).IsInsensitiveLike("tEsT", MatchMode.Anywhere))
+ .And(Restrictions.WhereProperty<Person>(p => p.Children).IsEmpty)
+ .And(Restrictions.WhereProperty<Person>(p => p.Children).IsNotEmpty)
+ .And(Restrictions.WhereProperty<Person>(p => p.Name).IsNotNull)
+ .And(Restrictions.WhereProperty<Person>(p => p.Name).IsNull)
+ .And(Restrictions.WhereProperty<Person>(p => p.Name).IsLike("%test%"))
+ .And(Restrictions.WhereProperty<Person>(p => p.Name).IsLike("test", MatchMode.Anywhere))
+ .And(Restrictions.WhereProperty<Person>(p => p.Name).IsLike("test", MatchMode.Anywhere, '?'));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-19 14:46:25
|
Revision: 4838
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4838&view=rev
Author: ricbrown
Date: 2009-11-19 14:46:12 +0000 (Thu, 19 Nov 2009)
Log Message:
-----------
Added remaining Restrictions overloads for lambda expressions.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Junction.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/NaturalIdentifier.cs
trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaNaturalIdentifierBuilder.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/Junction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Junction.cs 2009-11-19 12:31:20 UTC (rev 4837)
+++ trunk/nhibernate/src/NHibernate/Criterion/Junction.cs 2009-11-19 14:46:12 UTC (rev 4838)
@@ -1,9 +1,11 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Linq.Expressions;
using NHibernate.Engine;
+using NHibernate.Impl;
using NHibernate.SqlCommand;
using NHibernate.Util;
-using System.Collections.Generic;
namespace NHibernate.Criterion
{
@@ -31,6 +33,28 @@
}
/// <summary>
+ /// Adds an <see cref="ICriterion"/> to the list of <see cref="ICriterion"/>s
+ /// to junction together.
+ /// </summary>
+ public Junction Add<T>(Expression<Func<T, bool>> expression)
+ {
+ ICriterion criterion = ExpressionProcessor.ProcessExpression<T>(expression);
+ criteria.Add(criterion);
+ return this;
+ }
+
+ /// <summary>
+ /// Adds an <see cref="ICriterion"/> to the list of <see cref="ICriterion"/>s
+ /// to junction together.
+ /// </summary>
+ public Junction Add(Expression<Func<bool>> expression)
+ {
+ ICriterion criterion = ExpressionProcessor.ProcessExpression(expression);
+ criteria.Add(criterion);
+ return this;
+ }
+
+ /// <summary>
/// Get the Sql operator to put between multiple <see cref="ICriterion"/>s.
/// </summary>
protected abstract String Op { get; }
Added: trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaNaturalIdentifierBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaNaturalIdentifierBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaNaturalIdentifierBuilder.cs 2009-11-19 14:46:12 UTC (rev 4838)
@@ -0,0 +1,31 @@
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class LambdaNaturalIdentifierBuilder
+ {
+ private NaturalIdentifier naturalIdentifier;
+ private string propertyName;
+
+ public LambdaNaturalIdentifierBuilder(NaturalIdentifier naturalIdentifier, string propertyName)
+ {
+ this.naturalIdentifier = naturalIdentifier;
+ this.propertyName = propertyName;
+ }
+
+ public NaturalIdentifier Is(object value)
+ {
+ return naturalIdentifier.Set(propertyName, value);
+ }
+
+ }
+
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs 2009-11-19 12:31:20 UTC (rev 4837)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/LambdaRestrictionBuilder.cs 2009-11-19 14:46:12 UTC (rev 4838)
@@ -1,5 +1,6 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
@@ -47,6 +48,30 @@
}
/// <summary>
+ /// Apply an "in" constraint to the named property
+ /// </summary>
+ public AbstractCriterion IsIn(ICollection values)
+ {
+ return Restrictions.In(propertyName, values);
+ }
+
+ /// <summary>
+ /// Apply an "in" constraint to the named property
+ /// </summary>
+ public AbstractCriterion IsIn(object[] values)
+ {
+ return Restrictions.In(propertyName, values);
+ }
+
+ /// <summary>
+ /// Apply an "in" constraint to the named property
+ /// </summary>
+ public AbstractCriterion IsInG<T>(ICollection<T> values)
+ {
+ return Restrictions.InG(propertyName, values);
+ }
+
+ /// <summary>
/// A case-insensitive "like", similar to Postgres "ilike" operator
/// </summary>
public AbstractCriterion IsInsensitiveLike(object value)
Modified: trunk/nhibernate/src/NHibernate/Criterion/NaturalIdentifier.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/NaturalIdentifier.cs 2009-11-19 12:31:20 UTC (rev 4837)
+++ trunk/nhibernate/src/NHibernate/Criterion/NaturalIdentifier.cs 2009-11-19 14:46:12 UTC (rev 4838)
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
+using System.Linq.Expressions;
+using NHibernate.Criterion.Lambda;
using NHibernate.Engine;
+using NHibernate.Impl;
using NHibernate.SqlCommand;
namespace NHibernate.Criterion
@@ -31,5 +34,17 @@
conjunction.Add(Restrictions.Eq(property, value));
return this;
}
+
+ public LambdaNaturalIdentifierBuilder Set<T>(Expression<Func<T, object>> expression)
+ {
+ string property = ExpressionProcessor.FindMemberExpression(expression.Body);
+ return new LambdaNaturalIdentifierBuilder(this, property);
+ }
+
+ public LambdaNaturalIdentifierBuilder Set(Expression<Func<object>> expression)
+ {
+ string property = ExpressionProcessor.FindMemberExpression(expression.Body);
+ return new LambdaNaturalIdentifierBuilder(this, property);
+ }
}
}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2009-11-19 12:31:20 UTC (rev 4837)
+++ trunk/nhibernate/src/NHibernate/Criterion/Restrictions.cs 2009-11-19 14:46:12 UTC (rev 4838)
@@ -760,11 +760,34 @@
}
/// <summary>
+ /// Create an ICriterion for the negation of the supplied LambdaExpression
+ /// </summary>
+ /// <typeparam name="T">generic type</typeparam>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>return NHibernate.Criterion.ICriterion</returns>
+ public static ICriterion WhereNot<T>(Expression<Func<T, bool>> expression)
+ {
+ ICriterion criterion = ExpressionProcessor.ProcessExpression<T>(expression);
+ return Restrictions.Not(criterion);
+ }
+
+ /// <summary>
+ /// Create an ICriterion for the negation of the supplied LambdaExpression
+ /// </summary>
+ /// <param name="expression">lambda expression</param>
+ /// <returns>return NHibernate.Criterion.ICriterion</returns>
+ public static ICriterion WhereNot(Expression<Func<bool>> expression)
+ {
+ ICriterion criterion = ExpressionProcessor.ProcessExpression(expression);
+ return Restrictions.Not(criterion);
+ }
+
+ /// <summary>
/// Build an ICriterion for the given property
/// </summary>
/// <param name="expression">lambda expression identifying property</param>
/// <returns>returns LambdaRestrictionBuilder</returns>
- public static LambdaRestrictionBuilder WhereProperty<T>(Expression<Func<T, object>> expression)
+ public static LambdaRestrictionBuilder On<T>(Expression<Func<T, object>> expression)
{
string property = ExpressionProcessor.FindMemberExpression(expression.Body);
return new LambdaRestrictionBuilder(property);
@@ -775,7 +798,7 @@
/// </summary>
/// <param name="expression">lambda expression identifying property</param>
/// <returns>returns LambdaRestrictionBuilder</returns>
- public static LambdaRestrictionBuilder WhereProperty(Expression<Func<object>> expression)
+ public static LambdaRestrictionBuilder On(Expression<Func<object>> expression)
{
string property = ExpressionProcessor.FindMemberExpression(expression.Body);
return new LambdaRestrictionBuilder(property);
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-19 12:31:20 UTC (rev 4837)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-19 14:46:12 UTC (rev 4838)
@@ -505,6 +505,7 @@
<Compile Include="Context\WcfOperationSessionContext.cs" />
<Compile Include="Criterion\GroupedProjection.cs" />
<Compile Include="Criterion\IPropertyProjection.cs" />
+ <Compile Include="Criterion\Lambda\LambdaNaturalIdentifierBuilder.cs" />
<Compile Include="Criterion\Lambda\LambdaRestrictionBuilder.cs" />
<Compile Include="Criterion\Lambda\LambdaSubqueryBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverFetchBuilder.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-19 12:31:20 UTC (rev 4837)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-19 14:46:12 UTC (rev 4838)
@@ -18,24 +18,31 @@
ICriteria expected =
CreateTestCriteria(typeof(Person), "personAlias")
.Add(Restrictions.Lt("Age", 65))
- .Add(Restrictions.Ge("personAlias.Age", 18));
+ .Add(Restrictions.Ge("personAlias.Age", 18))
+ .Add(Restrictions.Not(Restrictions.Ge("Age", 65)))
+ .Add(Restrictions.Not(Restrictions.Lt("personAlias.Age", 18)));
Person personAlias = null;
var actual =
CreateTestQueryOver<Person>(() => personAlias)
.Where(Restrictions.Where<Person>(p => p.Age < 65))
- .And(Restrictions.Where(() => personAlias.Age >= 18));
+ .And(Restrictions.Where(() => personAlias.Age >= 18))
+ .And(Restrictions.WhereNot<Person>(p => p.Age >= 65))
+ .And(Restrictions.WhereNot(() => personAlias.Age < 18));
AssertCriteriaAreEqual(expected, actual);
}
[Test]
- public void SqlFunctions()
+ public void SqlOperators()
{
ICriteria expected =
CreateTestCriteria(typeof(Person), "personAlias")
.Add(Restrictions.Between("Age", 18, 65))
.Add(Restrictions.Between("personAlias.Age", 18, 65))
+ .Add(Restrictions.In("Name", new string[] { "name1", "name2", "name3" }))
+ .Add(Restrictions.In("Name", new ArrayList() { "name1", "name2", "name3" }))
+ .Add(Restrictions.InG<int>("Age", new int[] { 1, 2, 3 }))
.Add(Restrictions.InsensitiveLike("Name", "test"))
.Add(Restrictions.InsensitiveLike("Name", "tEsT", MatchMode.Anywhere))
.Add(Restrictions.IsEmpty("Children"))
@@ -44,26 +51,60 @@
.Add(Restrictions.IsNull("Name"))
.Add(Restrictions.Like("Name", "%test%"))
.Add(Restrictions.Like("Name", "test", MatchMode.Anywhere))
- .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere, '?'));
+ .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere, '?'))
+ .Add(Restrictions.NaturalId()
+ .Set("Name", "my name")
+ .Set("personAlias.Age", 18));
Person personAlias = null;
var actual =
CreateTestQueryOver<Person>(() => personAlias)
- .Where(Restrictions.WhereProperty<Person>(p => p.Age).IsBetween(18).And(65))
- .And(Restrictions.WhereProperty(() => personAlias.Age).IsBetween(18).And(65))
- .And(Restrictions.WhereProperty<Person>(p => p.Name).IsInsensitiveLike("test"))
- .And(Restrictions.WhereProperty<Person>(p => p.Name).IsInsensitiveLike("tEsT", MatchMode.Anywhere))
- .And(Restrictions.WhereProperty<Person>(p => p.Children).IsEmpty)
- .And(Restrictions.WhereProperty<Person>(p => p.Children).IsNotEmpty)
- .And(Restrictions.WhereProperty<Person>(p => p.Name).IsNotNull)
- .And(Restrictions.WhereProperty<Person>(p => p.Name).IsNull)
- .And(Restrictions.WhereProperty<Person>(p => p.Name).IsLike("%test%"))
- .And(Restrictions.WhereProperty<Person>(p => p.Name).IsLike("test", MatchMode.Anywhere))
- .And(Restrictions.WhereProperty<Person>(p => p.Name).IsLike("test", MatchMode.Anywhere, '?'));
+ .Where(Restrictions.On<Person>(p => p.Age).IsBetween(18).And(65))
+ .And(Restrictions.On(() => personAlias.Age).IsBetween(18).And(65))
+ .And(Restrictions.On<Person>(p => p.Name).IsIn(new string[] { "name1", "name2", "name3" }))
+ .And(Restrictions.On<Person>(p => p.Name).IsIn(new ArrayList() { "name1", "name2", "name3" }))
+ .And(Restrictions.On<Person>(p => p.Age).IsInG<int>(new int[] { 1, 2, 3 }))
+ .And(Restrictions.On<Person>(p => p.Name).IsInsensitiveLike("test"))
+ .And(Restrictions.On<Person>(p => p.Name).IsInsensitiveLike("tEsT", MatchMode.Anywhere))
+ .And(Restrictions.On<Person>(p => p.Children).IsEmpty)
+ .And(Restrictions.On<Person>(p => p.Children).IsNotEmpty)
+ .And(Restrictions.On<Person>(p => p.Name).IsNotNull)
+ .And(Restrictions.On<Person>(p => p.Name).IsNull)
+ .And(Restrictions.On<Person>(p => p.Name).IsLike("%test%"))
+ .And(Restrictions.On<Person>(p => p.Name).IsLike("test", MatchMode.Anywhere))
+ .And(Restrictions.On<Person>(p => p.Name).IsLike("test", MatchMode.Anywhere, '?'))
+ .And(Restrictions.NaturalId()
+ .Set<Person>(p => p.Name).Is("my name")
+ .Set(() => personAlias.Age).Is(18));
AssertCriteriaAreEqual(expected, actual);
}
+ [Test]
+ public void Junction()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Restrictions.Conjunction()
+ .Add(Restrictions.Eq("Name", "test"))
+ .Add(Restrictions.Eq("personAlias.Name", "test")))
+ .Add(Restrictions.Disjunction()
+ .Add(Restrictions.Eq("Name", "test"))
+ .Add(Restrictions.Eq("personAlias.Name", "test")));
+
+ Person personAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .Where(Restrictions.Conjunction()
+ .Add<Person>(p => p.Name == "test")
+ .Add(() => personAlias.Name == "test"))
+ .And(Restrictions.Disjunction()
+ .Add<Person>(p => p.Name == "test")
+ .Add(() => personAlias.Name == "test"));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-19 16:04:51
|
Revision: 4839
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4839&view=rev
Author: ricbrown
Date: 2009-11-19 16:04:43 +0000 (Thu, 19 Nov 2009)
Log Message:
-----------
Added typed inline restrictions to QueryOver.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate/IQueryOver.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs
Added: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs 2009-11-19 16:04:43 UTC (rev 4839)
@@ -0,0 +1,169 @@
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class QueryOverRestrictionBuilder<T> : QueryOverRestrictionBuilderBase<QueryOver<T>, T>
+ {
+
+ public QueryOverRestrictionBuilder(QueryOver<T> root, string propertyName)
+ : base(root, propertyName) { }
+
+ }
+
+ public class IQueryOverRestrictionBuilder<T> : QueryOverRestrictionBuilderBase<IQueryOver<T>, T>
+ {
+
+ public IQueryOverRestrictionBuilder(IQueryOver<T> root, string propertyName)
+ : base(root, propertyName) { }
+
+ }
+
+ public class QueryOverRestrictionBuilderBase<R, T>
+ where R : IQueryOver<T>
+ {
+ public class LambdaBetweenBuilder
+ {
+ private R root;
+ private string propertyName;
+ private object lo;
+
+ public LambdaBetweenBuilder(R root, string propertyName, object lo)
+ {
+ this.root = root;
+ this.propertyName = propertyName;
+ this.lo = lo;
+ }
+
+ public R And(object hi)
+ {
+ return (R)root.And(Restrictions.Between(propertyName, lo, hi));
+ }
+ }
+
+ private R root;
+ private string propertyName;
+
+ /// <summary>
+ /// Constructed with property name
+ /// </summary>
+ public QueryOverRestrictionBuilderBase(R root, string propertyName)
+ {
+ this.root = root;
+ this.propertyName = propertyName;
+ }
+
+ /// <summary>
+ /// Apply a "between" constraint to the named property
+ /// </summary>
+ public LambdaBetweenBuilder IsBetween(object lo)
+ {
+ return new LambdaBetweenBuilder(root, propertyName, lo);
+ }
+
+ /// <summary>
+ /// Apply an "in" constraint to the named property
+ /// </summary>
+ public R IsIn(ICollection values)
+ {
+ return (R)root.And(Restrictions.In(propertyName, values));
+ }
+
+ /// <summary>
+ /// Apply an "in" constraint to the named property
+ /// </summary>
+ public R IsIn(object[] values)
+ {
+ return (R)root.And(Restrictions.In(propertyName, values));
+ }
+
+ /// <summary>
+ /// Apply an "in" constraint to the named property
+ /// </summary>
+ public R IsInG<T>(ICollection<T> values)
+ {
+ return (R)root.And(Restrictions.InG(propertyName, values));
+ }
+
+ /// <summary>
+ /// A case-insensitive "like", similar to Postgres "ilike" operator
+ /// </summary>
+ public R IsInsensitiveLike(object value)
+ {
+ return (R)root.And(Restrictions.InsensitiveLike(propertyName, value));
+ }
+
+ /// <summary>
+ /// A case-insensitive "like", similar to Postgres "ilike" operator
+ /// </summary>
+ public R IsInsensitiveLike(string value, MatchMode matchMode)
+ {
+ return (R)root.And(Restrictions.InsensitiveLike(propertyName, value, matchMode));
+ }
+
+ /// <summary>
+ /// Apply an "is empty" constraint to the named property
+ /// </summary>
+ public R IsEmpty
+ {
+ get { return (R)root.And(Restrictions.IsEmpty(propertyName)); }
+ }
+
+ /// <summary>
+ /// Apply a "not is empty" constraint to the named property
+ /// </summary>
+ public R IsNotEmpty
+ {
+ get { return (R)root.And(Restrictions.IsNotEmpty(propertyName)); }
+ }
+
+ /// <summary>
+ /// Apply an "is null" constraint to the named property
+ /// </summary>
+ public R IsNull
+ {
+ get { return (R)root.And(Restrictions.IsNull(propertyName)); }
+ }
+
+ /// <summary>
+ /// Apply an "not is null" constraint to the named property
+ /// </summary>
+ public R IsNotNull
+ {
+ get { return (R)root.And(Restrictions.IsNotNull(propertyName)); }
+ }
+
+ /// <summary>
+ /// Apply a "like" constraint to the named property
+ /// </summary>
+ public R IsLike(object value)
+ {
+ return (R)root.And(Restrictions.Like(propertyName, value));
+ }
+
+ /// <summary>
+ /// Apply a "like" constraint to the named property
+ /// </summary>
+ public R IsLike(string value, MatchMode matchMode)
+ {
+ return (R)root.And(Restrictions.Like(propertyName, value, matchMode));
+ }
+
+ /// <summary>
+ /// Apply a "like" constraint to the named property
+ /// </summary>
+ public R IsLike(string value, MatchMode matchMode, char? escapeChar)
+ {
+ return (R)root.And(Restrictions.Like(propertyName, value, matchMode, escapeChar));
+ }
+
+ }
+
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-19 14:46:12 UTC (rev 4838)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-19 16:04:43 UTC (rev 4839)
@@ -89,6 +89,16 @@
return Add(expression);
}
+ public QueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<T, object>> expression)
+ {
+ return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ public QueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<object>> expression)
+ {
+ return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
public QueryOver<T> Where(Expression<Func<T, bool>> expression)
{
return Add(expression);
@@ -104,6 +114,16 @@
return Add(expression);
}
+ public QueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<T, object>> expression)
+ {
+ return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ public QueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<object>> expression)
+ {
+ return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
public QueryOver<T> Select(params Expression<Func<T, object>>[] projections)
{
List<IProjection> projectionList = new List<IProjection>();
@@ -457,6 +477,12 @@
IQueryOver<T> IQueryOver<T>.And(ICriterion expression)
{ return And(expression); }
+ IQueryOverRestrictionBuilder<T> IQueryOver<T>.AndRestrictionOn(Expression<Func<T, object>> expression)
+ { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
+
+ IQueryOverRestrictionBuilder<T> IQueryOver<T>.AndRestrictionOn(Expression<Func<object>> expression)
+ { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
+
IQueryOver<T> IQueryOver<T>.Where(Expression<Func<T, bool>> expression)
{ return Where(expression); }
@@ -466,6 +492,12 @@
IQueryOver<T> IQueryOver<T>.Where(ICriterion expression)
{ return Where(expression); }
+ IQueryOverRestrictionBuilder<T> IQueryOver<T>.WhereRestrictionOn(Expression<Func<T, object>> expression)
+ { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
+
+ IQueryOverRestrictionBuilder<T> IQueryOver<T>.WhereRestrictionOn(Expression<Func<object>> expression)
+ { return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
+
IQueryOver<T> IQueryOver<T>.Select(params Expression<Func<T, object>>[] projections)
{ return Select(projections); }
Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-19 14:46:12 UTC (rev 4838)
+++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-19 16:04:43 UTC (rev 4839)
@@ -50,6 +50,20 @@
IQueryOver<T> And(ICriterion expression);
/// <summary>
+ /// Add restriction to a property
+ /// </summary>
+ /// <param name="expression">Lambda expression containing path to property</param>
+ /// <returns>criteria instance</returns>
+ IQueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<T, object>> expression);
+
+ /// <summary>
+ /// Add restriction to a property
+ /// </summary>
+ /// <param name="expression">Lambda expression containing path to property</param>
+ /// <returns>criteria instance</returns>
+ IQueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<object>> expression);
+
+ /// <summary>
/// Identical semantics to Add() to allow more readable queries
/// </summary>
/// <param name="expression">Lambda expression</param>
@@ -69,6 +83,20 @@
IQueryOver<T> Where(ICriterion expression);
/// <summary>
+ /// Identical semantics to AndRestrictionOn() to allow more readable queries
+ /// </summary>
+ /// <param name="expression">Lambda expression</param>
+ /// <returns>criteria instance</returns>
+ IQueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<T, object>> expression);
+
+ /// <summary>
+ /// Identical semantics to AndRestrictionOn() to allow more readable queries
+ /// </summary>
+ /// <param name="expression">Lambda expression</param>
+ /// <returns>criteria instance</returns>
+ IQueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<object>> expression);
+
+ /// <summary>
/// Add projection expressed as a lambda expression
/// </summary>
/// <param name="projections">Lambda expressions</param>
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-19 14:46:12 UTC (rev 4838)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-19 16:04:43 UTC (rev 4839)
@@ -512,6 +512,7 @@
<Compile Include="Criterion\Lambda\QueryOverJoinBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverLockBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverOrderBuilder.cs" />
+ <Compile Include="Criterion\Lambda\QueryOverRestrictionBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverSubqueryBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverSubqueryPropertyBuilder.cs" />
<Compile Include="Dialect\MsSql2008Dialect.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-19 14:46:12 UTC (rev 4838)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-19 16:04:43 UTC (rev 4839)
@@ -105,6 +105,68 @@
AssertCriteriaAreEqual(expected, actual);
}
+ [Test]
+ public void SqlOperatorsInline()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Restrictions.Between("Age", 18, 65))
+ .Add(Restrictions.Between("personAlias.Age", 18, 65))
+ .Add(Restrictions.In("Name", new string[] { "name1", "name2", "name3" }))
+ .Add(Restrictions.In("personAlias.Name", new ArrayList() { "name1", "name2", "name3" }))
+ .Add(Restrictions.InG<int>("Age", new int[] { 1, 2, 3 }))
+ .Add(Restrictions.InsensitiveLike("Name", "test"))
+ .Add(Restrictions.InsensitiveLike("Name", "tEsT", MatchMode.Anywhere))
+ .Add(Restrictions.IsEmpty("Children"))
+ .Add(Restrictions.IsNotEmpty("Children"))
+ .Add(Restrictions.IsNotNull("Name"))
+ .Add(Restrictions.IsNull("Name"))
+ .Add(Restrictions.Like("Name", "%test%"))
+ .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere))
+ .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere, '?'));
+
+ Person personAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .WhereRestrictionOn(p => p.Age).IsBetween(18).And(65)
+ .WhereRestrictionOn(() => personAlias.Age).IsBetween(18).And(65)
+ .AndRestrictionOn(p => p.Name).IsIn(new string[] { "name1", "name2", "name3" })
+ .AndRestrictionOn(() => personAlias.Name).IsIn(new ArrayList() { "name1", "name2", "name3" })
+ .AndRestrictionOn(p => p.Age).IsInG<int>(new int[] { 1, 2, 3 })
+ .AndRestrictionOn(p => p.Name).IsInsensitiveLike("test")
+ .AndRestrictionOn(p => p.Name).IsInsensitiveLike("tEsT", MatchMode.Anywhere)
+ .AndRestrictionOn(p => p.Children).IsEmpty
+ .AndRestrictionOn(p => p.Children).IsNotEmpty
+ .AndRestrictionOn(p => p.Name).IsNotNull
+ .AndRestrictionOn(p => p.Name).IsNull
+ .AndRestrictionOn(p => p.Name).IsLike("%test%")
+ .AndRestrictionOn(p => p.Name).IsLike("test", MatchMode.Anywhere)
+ .AndRestrictionOn(p => p.Name).IsLike("test", MatchMode.Anywhere, '?');
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
+ public void DetachedRestrictions()
+ {
+ DetachedCriteria expected =
+ DetachedCriteria.For<Person>("personAlias")
+ .Add(Restrictions.Between("Age", 18, 65))
+ .Add(Restrictions.Between("personAlias.Age", 18, 65))
+ .Add(Restrictions.In("Name", new string[] { "name1", "name2", "name3" }))
+ .Add(Restrictions.In("personAlias.Name", new ArrayList() { "name1", "name2", "name3" }));
+
+ Person personAlias = null;
+ QueryOver<Person> actual =
+ new QueryOver<Person>(() => personAlias)
+ .WhereRestrictionOn(p => p.Age).IsBetween(18).And(65)
+ .WhereRestrictionOn(() => personAlias.Age).IsBetween(18).And(65)
+ .AndRestrictionOn(p => p.Name).IsIn(new string[] { "name1", "name2", "name3" })
+ .AndRestrictionOn(() => personAlias.Name).IsIn(new ArrayList() { "name1", "name2", "name3" });
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fab...@us...> - 2009-11-20 20:14:05
|
Revision: 4847
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4847&view=rev
Author: fabiomaulo
Date: 2009-11-20 20:13:57 +0000 (Fri, 20 Nov 2009)
Log Message:
-----------
Merge r4846 (fix NH-2011)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs
Modified: trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2009-11-20 20:00:56 UTC (rev 4846)
+++ trunk/nhibernate/src/NHibernate/Type/TypeFactory.cs 2009-11-20 20:13:57 UTC (rev 4847)
@@ -1125,8 +1125,10 @@
? new object[subtypes.Length]
: componentType.GetPropertyValues(original[i], session);
object[] targetComponentValues = componentType.GetPropertyValues(target[i], session);
- ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache,
+ object[] componentCopy = ReplaceAssociations(origComponentValues, targetComponentValues, subtypes, session, null, copyCache,
foreignKeyDirection);
+ if (!componentType.IsAnyType)
+ componentType.SetPropertyValues(target[i], componentCopy, session.EntityMode);
copied[i] = target[i];
}
else if (!types[i].IsAssociationType)
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Fixture.cs 2009-11-20 20:13:57 UTC (rev 4847)
@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH2011
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ [Test]
+ public void Test()
+ {
+ using (ISession session = OpenSession())
+ {
+ using (ITransaction tx = session.BeginTransaction())
+ {
+ session.Save(new Country {CountryCode = "SE"});
+ tx.Commit();
+ }
+ }
+
+ var newOrder = new Order();
+ newOrder.GroupComponent = new GroupComponent();
+ newOrder.GroupComponent.Countries = new List<Country>();
+ newOrder.GroupComponent.Countries.Add(new Country {CountryCode = "SE"});
+
+ Order mergedCopy;
+ using (ISession session = OpenSession())
+ {
+ using (ITransaction tx = session.BeginTransaction())
+ {
+ mergedCopy = (Order) session.Merge(newOrder);
+ tx.Commit();
+ }
+ }
+
+ using (ISession session = OpenSession())
+ {
+ var order = session.Get<Order>(mergedCopy.Id);
+ Assert.That(order.GroupComponent.Countries.Count, Is.EqualTo(1));
+ }
+
+ using (ISession session = OpenSession())
+ {
+ using (ITransaction tx = session.BeginTransaction())
+ {
+ session.Delete("from Order");
+ session.Delete("from Country");
+ tx.Commit();
+ }
+ }
+ }
+ }
+}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Mappings.hbm.xml 2009-11-20 20:13:57 UTC (rev 4847)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.NHSpecificTest.NH2011">
+
+ <class name="Order" table="Orders">
+
+ <id name="Id">
+ <generator class="guid.comb"/>
+ </id>
+
+ <component name="GroupComponent">
+
+ <bag name="Countries" table="OrderCountries" cascade="none">
+ <key column="OrderId" />
+ <many-to-many column="CountryCode" class="Country" />
+ </bag>
+
+ </component>
+
+ </class>
+
+ <class name="Country" table="Countries">
+
+ <id name="CountryCode" unsaved-value="null">
+ <generator class="assigned"/>
+ </id>
+
+ </class>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2011/Model.cs 2009-11-20 20:13:57 UTC (rev 4847)
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+
+namespace NHibernate.Test.NHSpecificTest.NH2011
+{
+ public class Order
+ {
+ public virtual Guid Id { get; set; }
+
+ public virtual GroupComponent GroupComponent { get; set; }
+ }
+
+ public class GroupComponent
+ {
+ public virtual IList<Country> Countries { get; set; }
+ }
+
+ public class Country
+ {
+ public virtual string CountryCode { get; set; }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-20 20:00:56 UTC (rev 4846)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-20 20:13:57 UTC (rev 4847)
@@ -665,6 +665,8 @@
<Compile Include="NHSpecificTest\NH2000\SampleTest.cs" />
<Compile Include="NHSpecificTest\NH2003\Fixture.cs" />
<Compile Include="NHSpecificTest\NH2003\Model.cs" />
+ <Compile Include="NHSpecificTest\NH2011\Fixture.cs" />
+ <Compile Include="NHSpecificTest\NH2011\Model.cs" />
<Compile Include="NHSpecificTest\NH473\Child.cs" />
<Compile Include="NHSpecificTest\NH473\Fixture.cs" />
<Compile Include="NHSpecificTest\NH473\Parent.cs" />
@@ -2078,6 +2080,7 @@
<EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" />
<EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" />
<Content Include="DynamicEntity\package.html" />
+ <EmbeddedResource Include="NHSpecificTest\NH2011\Mappings.hbm.xml" />
<EmbeddedResource Include="Linq\Mappings\Animal.hbm.xml" />
<EmbeddedResource Include="Linq\Mappings\AnotherEntity.hbm.xml" />
<EmbeddedResource Include="Linq\Mappings\Role.hbm.xml" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-20 21:28:58
|
Revision: 4848
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4848&view=rev
Author: ricbrown
Date: 2009-11-20 21:28:47 +0000 (Fri, 20 Nov 2009)
Log Message:
-----------
Added convenience syntax for negation of expressions.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate/IQueryOver.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-20 20:13:57 UTC (rev 4847)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-20 21:28:47 UTC (rev 4848)
@@ -89,6 +89,16 @@
return Add(expression);
}
+ public QueryOver<T> AndNot(Expression<Func<T, bool>> expression)
+ {
+ return AddNot(expression);
+ }
+
+ public QueryOver<T> AndNot(Expression<Func<bool>> expression)
+ {
+ return AddNot(expression);
+ }
+
public QueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<T, object>> expression)
{
return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
@@ -114,6 +124,16 @@
return Add(expression);
}
+ public QueryOver<T> WhereNot(Expression<Func<T, bool>> expression)
+ {
+ return AddNot(expression);
+ }
+
+ public QueryOver<T> WhereNot(Expression<Func<bool>> expression)
+ {
+ return AddNot(expression);
+ }
+
public QueryOverRestrictionBuilder<T> WhereRestrictionOn(Expression<Func<T, object>> expression)
{
return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
@@ -464,7 +484,19 @@
return this;
}
+ private QueryOver<T> AddNot(Expression<Func<T, bool>> expression)
+ {
+ _criteria.Add(Restrictions.Not(ExpressionProcessor.ProcessExpression<T>(expression)));
+ return this;
+ }
+ private QueryOver<T> AddNot(Expression<Func<bool>> expression)
+ {
+ _criteria.Add(Restrictions.Not(ExpressionProcessor.ProcessExpression(expression)));
+ return this;
+ }
+
+
ICriteria IQueryOver<T>.UnderlyingCriteria
{ get { return UnderlyingCriteria; } }
@@ -477,6 +509,12 @@
IQueryOver<T> IQueryOver<T>.And(ICriterion expression)
{ return And(expression); }
+ IQueryOver<T> IQueryOver<T>.AndNot(Expression<Func<T, bool>> expression)
+ { return AndNot(expression); }
+
+ IQueryOver<T> IQueryOver<T>.AndNot(Expression<Func<bool>> expression)
+ { return AndNot(expression); }
+
IQueryOverRestrictionBuilder<T> IQueryOver<T>.AndRestrictionOn(Expression<Func<T, object>> expression)
{ return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
@@ -492,6 +530,12 @@
IQueryOver<T> IQueryOver<T>.Where(ICriterion expression)
{ return Where(expression); }
+ IQueryOver<T> IQueryOver<T>.WhereNot(Expression<Func<T, bool>> expression)
+ { return WhereNot(expression); }
+
+ IQueryOver<T> IQueryOver<T>.WhereNot(Expression<Func<bool>> expression)
+ { return WhereNot(expression); }
+
IQueryOverRestrictionBuilder<T> IQueryOver<T>.WhereRestrictionOn(Expression<Func<T, object>> expression)
{ return new IQueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body)); }
Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-20 20:13:57 UTC (rev 4847)
+++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-20 21:28:47 UTC (rev 4848)
@@ -50,6 +50,20 @@
IQueryOver<T> And(ICriterion expression);
/// <summary>
+ /// Add negation of criterion expressed as a lambda expression
+ /// </summary>
+ /// <param name="expression">Lambda expression</param>
+ /// <returns>criteria instance</returns>
+ IQueryOver<T> AndNot(Expression<Func<T, bool>> expression);
+
+ /// <summary>
+ /// Add negation of criterion expressed as a lambda expression
+ /// </summary>
+ /// <param name="expression">Lambda expression</param>
+ /// <returns>criteria instance</returns>
+ IQueryOver<T> AndNot(Expression<Func<bool>> expression);
+
+ /// <summary>
/// Add restriction to a property
/// </summary>
/// <param name="expression">Lambda expression containing path to property</param>
@@ -64,14 +78,14 @@
IQueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<object>> expression);
/// <summary>
- /// Identical semantics to Add() to allow more readable queries
+ /// Identical semantics to And() to allow more readable queries
/// </summary>
/// <param name="expression">Lambda expression</param>
/// <returns>criteria instance</returns>
IQueryOver<T> Where(Expression<Func<T, bool>> expression);
/// <summary>
- /// Identical semantics to Add() to allow more readable queries
+ /// Identical semantics to And() to allow more readable queries
/// </summary>
/// <param name="expression">Lambda expression</param>
/// <returns>criteria instance</returns>
@@ -83,6 +97,20 @@
IQueryOver<T> Where(ICriterion expression);
/// <summary>
+ /// Identical semantics to AndNot() to allow more readable queries
+ /// </summary>
+ /// <param name="expression">Lambda expression</param>
+ /// <returns>criteria instance</returns>
+ IQueryOver<T> WhereNot(Expression<Func<T, bool>> expression);
+
+ /// <summary>
+ /// Identical semantics to AndNot() to allow more readable queries
+ /// </summary>
+ /// <param name="expression">Lambda expression</param>
+ /// <returns>criteria instance</returns>
+ IQueryOver<T> WhereNot(Expression<Func<bool>> expression);
+
+ /// <summary>
/// Identical semantics to AndRestrictionOn() to allow more readable queries
/// </summary>
/// <param name="expression">Lambda expression</param>
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-20 20:13:57 UTC (rev 4847)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-20 21:28:47 UTC (rev 4848)
@@ -101,18 +101,39 @@
}
[Test]
+ public void Negation()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .Add(Restrictions.Not(Restrictions.Eq("Name", "test name")))
+ .Add(Restrictions.Not(Restrictions.Eq("personAlias.Name", "test name")));
+
+ Person personAlias = null;
+ IQueryOver<Person> actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .AndNot(p => p.Name == "test name")
+ .AndNot(() => personAlias.Name == "test name");
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ [Test]
public void Where_BehavesTheSameAs_And()
{
Person personAlias = null;
QueryOver<Person> expected = (QueryOver<Person>)
CreateTestQueryOver<Person>(() => personAlias)
.And(() => personAlias.Name == "test name")
- .And(p => p.Name == "test name");
+ .And(p => p.Name == "test name")
+ .AndNot(() => personAlias.Name == "test name")
+ .AndNot(p => p.Name == "test name");
IQueryOver<Person> actual =
CreateTestQueryOver<Person>(() => personAlias)
.Where(() => personAlias.Name == "test name")
- .Where(p => p.Name == "test name");
+ .Where(p => p.Name == "test name")
+ .WhereNot(() => personAlias.Name == "test name")
+ .WhereNot(p => p.Name == "test name");
AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-23 17:38:18
|
Revision: 4855
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4855&view=rev
Author: ricbrown
Date: 2009-11-23 17:38:07 +0000 (Mon, 23 Nov 2009)
Log Message:
-----------
Added first cut of projections using Lambda expressions.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs
trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs 2009-11-22 15:34:59 UTC (rev 4854)
+++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionList.cs 2009-11-23 17:38:07 UTC (rev 4855)
@@ -1,7 +1,9 @@
using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using NHibernate.Impl;
using NHibernate.SqlCommand;
using NHibernate.Type;
-using System.Collections.Generic;
namespace NHibernate.Criterion
{
@@ -32,6 +34,11 @@
return Add(Projections.Alias(projection, alias));
}
+ public ProjectionList Add<T>(IProjection projection, Expression<Func<T>> alias)
+ {
+ return Add(projection, ExpressionProcessor.FindMemberExpression(alias.Body));
+ }
+
public IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
IList<IType> types = new List<IType>(Length);
Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-22 15:34:59 UTC (rev 4854)
+++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-23 17:38:07 UTC (rev 4855)
@@ -1,4 +1,6 @@
using System;
+using System.Linq.Expressions;
+using NHibernate.Impl;
using NHibernate.Type;
namespace NHibernate.Criterion
@@ -316,5 +318,138 @@
SelectSubqueryExpression expr = new SelectSubqueryExpression(detachedCriteria);
return new SubqueryProjection(expr);
}
+
+ /// <summary>
+ /// A property average value
+ /// </summary>
+ public static AggregateProjection Avg<T>(Expression<Func<T, object>> expression)
+ {
+ return Projections.Avg(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A property average value
+ /// </summary>
+ public static AggregateProjection Avg(Expression<Func<object>> expression)
+ {
+ return Projections.Avg(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A property value count
+ /// </summary>
+ public static CountProjection Count<T>(Expression<Func<T, object>> expression)
+ {
+ return Projections.Count(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A property value count
+ /// </summary>
+ public static CountProjection Count(Expression<Func<object>> expression)
+ {
+ return Projections.Count(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A distinct property value count
+ /// </summary>
+ public static CountProjection CountDistinct<T>(Expression<Func<T, object>> expression)
+ {
+ return Projections.CountDistinct(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A distinct property value count
+ /// </summary>
+ public static CountProjection CountDistinct(Expression<Func<object>> expression)
+ {
+ return Projections.CountDistinct(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A grouping property value
+ /// </summary>
+ public static PropertyProjection GroupProperty<T>(Expression<Func<T, object>> expression)
+ {
+ return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A grouping property value
+ /// </summary>
+ public static PropertyProjection GroupProperty(Expression<Func<object>> expression)
+ {
+ return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A property maximum value
+ /// </summary>
+ public static AggregateProjection Max<T>(Expression<Func<T, object>> expression)
+ {
+ return Projections.Max(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A property maximum value
+ /// </summary>
+ public static AggregateProjection Max(Expression<Func<object>> expression)
+ {
+ return Projections.Max(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A property minimum value
+ /// </summary>
+ public static AggregateProjection Min<T>(Expression<Func<T, object>> expression)
+ {
+ return Projections.Min(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A property minimum value
+ /// </summary>
+ public static AggregateProjection Min(Expression<Func<object>> expression)
+ {
+ return Projections.Min(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A projected property value
+ /// </summary>
+ public static PropertyProjection Property<T>(Expression<Func<T, object>> expression)
+ {
+ return Projections.Property(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A projected property value
+ /// </summary>
+ public static PropertyProjection Property(Expression<Func<object>> expression)
+ {
+ return Projections.Property(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ public static IProjection SubQuery<T>(QueryOver<T> detachedQueryOver)
+ {
+ return Projections.SubQuery(detachedQueryOver.DetachedCriteria);
+ }
+
+ /// <summary>
+ /// A property value sum
+ /// </summary>
+ public static AggregateProjection Sum<T>(Expression<Func<T, object>> expression)
+ {
+ return Projections.Sum(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
+
+ /// <summary>
+ /// A property value sum
+ /// </summary>
+ public static AggregateProjection Sum(Expression<Func<object>> expression)
+ {
+ return Projections.Sum(ExpressionProcessor.FindMemberExpression(expression.Body));
+ }
}
}
Added: trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/ProjectionsExtensions.cs 2009-11-23 17:38:07 UTC (rev 4855)
@@ -0,0 +1,23 @@
+using System;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+
+namespace NHibernate.Criterion
+{
+ public static class ProjectionsExtensions
+ {
+ /// <summary>
+ /// Create an alias for a projection
+ /// </summary>
+ /// <param name="projection">the projection instance</param>
+ /// <param name="alias">LambdaExpression returning an alias</param>
+ /// <returns>return NHibernate.Criterion.IProjection</returns>
+ public static IProjection WithAlias(this IProjection projection,
+ Expression<Func<object>> alias)
+ {
+ string aliasContainer = ExpressionProcessor.FindMemberExpression(alias.Body);
+ return Projections.Alias(projection, aliasContainer);
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-22 15:34:59 UTC (rev 4854)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-23 17:38:07 UTC (rev 4855)
@@ -515,6 +515,7 @@
<Compile Include="Criterion\Lambda\QueryOverRestrictionBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverSubqueryBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverSubqueryPropertyBuilder.cs" />
+ <Compile Include="Criterion\ProjectionsExtensions.cs" />
<Compile Include="Dialect\MsSql2008Dialect.cs" />
<Compile Include="Dialect\InformixDialect0940.cs" />
<Compile Include="Dialect\InformixDialect1000.cs" />
Added: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-23 17:38:07 UTC (rev 4855)
@@ -0,0 +1,90 @@
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+using NHibernate.Criterion;
+
+namespace NHibernate.Test.Criteria.Lambda
+{
+
+ [TestFixture]
+ public class ProjectionsFixture : LambdaFixtureBase
+ {
+
+ private Child _subqueryChildAlias = null;
+
+ private DetachedCriteria DetachedCriteriaAge
+ {
+ get
+ {
+ return ToDetachedCriteria(DetachedQueryOverAge);
+ }
+ }
+
+ private QueryOver<Child> DetachedQueryOverAge
+ {
+ get
+ {
+ return
+ new QueryOver<Child>(() => _subqueryChildAlias)
+ .Where(() => _subqueryChildAlias.Nickname == "subquery name")
+ .Select(p => p.Age);
+ }
+ }
+
+ [Test]
+ public void ArbitraryProjections()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.Alias(Projections.Avg("Age"), "personAgeProjectionAlias"))
+ .Add(Projections.Avg("Age"), "personAgeProjectionAlias")
+ .Add(Projections.Avg("personAlias.Age"))
+ .Add(Projections.Count("Age"))
+ .Add(Projections.Count("personAlias.Age"))
+ .Add(Projections.CountDistinct("Age"))
+ .Add(Projections.CountDistinct("personAlias.Age"))
+ .Add(Projections.GroupProperty("Age"))
+ .Add(Projections.GroupProperty("personAlias.Age"))
+ .Add(Projections.Max("Age"))
+ .Add(Projections.Max("personAlias.Age"))
+ .Add(Projections.Min("Age"))
+ .Add(Projections.Min("personAlias.Age"))
+ .Add(Projections.Property("Age"))
+ .Add(Projections.Property("personAlias.Age"))
+ .Add(Projections.SubQuery(DetachedCriteriaAge))
+ .Add(Projections.Sum("Age"))
+ .Add(Projections.Sum("personAlias.Age")));
+
+ Person personAlias = null;
+ Person personAgeProjectionAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .Select(Projections.ProjectionList()
+ .Add(Projections.Avg<Person>(p => p.Age).WithAlias(() => personAgeProjectionAlias))
+ .Add(Projections.Avg<Person>(p => p.Age), () => personAgeProjectionAlias)
+ .Add(Projections.Avg(() => personAlias.Age))
+ .Add(Projections.Count<Person>(p => p.Age))
+ .Add(Projections.Count(() => personAlias.Age))
+ .Add(Projections.CountDistinct<Person>(p => p.Age))
+ .Add(Projections.CountDistinct(() => personAlias.Age))
+ .Add(Projections.GroupProperty<Person>(p => p.Age))
+ .Add(Projections.GroupProperty(() => personAlias.Age))
+ .Add(Projections.Max<Person>(p => p.Age))
+ .Add(Projections.Max(() => personAlias.Age))
+ .Add(Projections.Min<Person>(p => p.Age))
+ .Add(Projections.Min(() => personAlias.Age))
+ .Add(Projections.Property<Person>(p => p.Age))
+ .Add(Projections.Property(() => personAlias.Age))
+ .Add(Projections.SubQuery(DetachedQueryOverAge))
+ .Add(Projections.Sum<Person>(p => p.Age))
+ .Add(Projections.Sum(() => personAlias.Age)));
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
+ }
+
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-22 15:34:59 UTC (rev 4854)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-11-23 17:38:07 UTC (rev 4855)
@@ -160,6 +160,7 @@
<Compile Include="Criteria\Enrolment.cs" />
<Compile Include="Criteria\Lambda\CriteriaAssertFixture.cs" />
<Compile Include="Criteria\Lambda\ExpressionProcessorFixture.cs" />
+ <Compile Include="Criteria\Lambda\ProjectionsFixture.cs" />
<Compile Include="Criteria\Lambda\QueryOverFixture.cs" />
<Compile Include="Criteria\Lambda\IntegrationFixture.cs" />
<Compile Include="Criteria\Lambda\LambdaFixtureBase.cs" />
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-23 18:00:28
|
Revision: 4856
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4856&view=rev
Author: ricbrown
Date: 2009-11-23 18:00:21 +0000 (Mon, 23 Nov 2009)
Log Message:
-----------
Moved creation of detached QueryOver of T to a factory method.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-23 17:38:07 UTC (rev 4855)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-23 18:00:21 UTC (rev 4856)
@@ -19,6 +19,16 @@
protected QueryOver() { }
+ public static QueryOver<T> Of<T>()
+ {
+ return new QueryOver<T>();
+ }
+
+ public static QueryOver<T> Of<T>(Expression<Func<T>> alias)
+ {
+ return new QueryOver<T>(alias);
+ }
+
public ICriteria UnderlyingCriteria
{
get { return _criteria; }
@@ -38,13 +48,13 @@
public class QueryOver<T> : QueryOver, IQueryOver<T>
{
- public QueryOver()
+ protected internal QueryOver()
{
_impl = new CriteriaImpl(typeof(T), null);
_criteria = _impl;
}
- public QueryOver(Expression<Func<T>> alias)
+ protected internal QueryOver(Expression<Func<T>> alias)
{
string aliasPath = ExpressionProcessor.FindMemberExpression(alias.Body);
_impl = new CriteriaImpl(typeof(T), aliasPath, null);
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2009-11-23 17:38:07 UTC (rev 4855)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2009-11-23 18:00:21 UTC (rev 4856)
@@ -81,7 +81,7 @@
using (ISession s = OpenSession())
{
QueryOver<Person> personQuery =
- new QueryOver<Person>()
+ QueryOver.Of<Person>()
.Where(p => p.Name == "test person 1");
IList<Person> actual =
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-23 17:38:07 UTC (rev 4855)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-23 18:00:21 UTC (rev 4856)
@@ -27,7 +27,7 @@
get
{
return
- new QueryOver<Child>(() => _subqueryChildAlias)
+ QueryOver.Of<Child>(() => _subqueryChildAlias)
.Where(() => _subqueryChildAlias.Nickname == "subquery name")
.Select(p => p.Age);
}
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-23 17:38:07 UTC (rev 4855)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2009-11-23 18:00:21 UTC (rev 4856)
@@ -477,7 +477,7 @@
Person personAlias = null;
QueryOver<Person> actual =
- new QueryOver<Person>(() => personAlias)
+ QueryOver.Of<Person>(() => personAlias)
.Where(() => personAlias.Name == "test name");
AssertCriteriaAreEqual(expected, actual);
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-23 17:38:07 UTC (rev 4855)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2009-11-23 18:00:21 UTC (rev 4856)
@@ -158,7 +158,7 @@
Person personAlias = null;
QueryOver<Person> actual =
- new QueryOver<Person>(() => personAlias)
+ QueryOver.Of<Person>(() => personAlias)
.WhereRestrictionOn(p => p.Age).IsBetween(18).And(65)
.WhereRestrictionOn(() => personAlias.Age).IsBetween(18).And(65)
.AndRestrictionOn(p => p.Name).IsIn(new string[] { "name1", "name2", "name3" })
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-23 17:38:07 UTC (rev 4855)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/SubqueryFixture.cs 2009-11-23 18:00:21 UTC (rev 4856)
@@ -47,7 +47,7 @@
get
{
return
- new QueryOver<Child>(() => _subqueryChildAlias)
+ QueryOver.Of<Child>(() => _subqueryChildAlias)
.Where(() => _subqueryChildAlias.Nickname == "subquery name");
}
}
@@ -57,7 +57,7 @@
get
{
return
- new QueryOver<Child>(() => _subqueryChildAlias)
+ QueryOver.Of<Child>(() => _subqueryChildAlias)
.Where(() => _subqueryChildAlias.Nickname == "subquery name")
.Select(p => p.Nickname);
}
@@ -68,7 +68,7 @@
get
{
return
- new QueryOver<Child>(() => _subqueryChildAlias)
+ QueryOver.Of<Child>(() => _subqueryChildAlias)
.Where(() => _subqueryChildAlias.Nickname == "subquery name")
.Select(p => p.Age);
}
@@ -112,7 +112,7 @@
Person personAlias = null;
QueryOver<Person> actual =
- new QueryOver<Person>(() => personAlias)
+ QueryOver.Of<Person>(() => personAlias)
.WithSubquery.WhereProperty(p => p.Name).Eq(DetachedQueryOverName)
.WithSubquery.WhereProperty(() => personAlias.Name).Eq(DetachedQueryOverName);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-25 18:36:17
|
Revision: 4857
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4857&view=rev
Author: ricbrown
Date: 2009-11-25 18:36:07 +0000 (Wed, 25 Nov 2009)
Log Message:
-----------
Added typed inline projections to QueryOver.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate/IQueryOver.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs
Added: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs 2009-11-25 18:36:07 UTC (rev 4857)
@@ -0,0 +1,223 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion.Lambda
+{
+
+ public class QueryOverProjectionBuilder<R, T>
+ {
+
+ private R fluentReturn;
+ private IQueryOver<T> criteria;
+ private ProjectionList projectionList;
+ private IProjection lastProjection = null;
+
+ public QueryOverProjectionBuilder(R fluentReturn, IQueryOver<T> criteria)
+ {
+ this.fluentReturn = fluentReturn;
+ this.criteria = criteria;
+ projectionList = Projections.ProjectionList();
+ }
+
+ private void AddLastProjection()
+ {
+ if (lastProjection != null)
+ projectionList.Add(lastProjection);
+ }
+
+ private void PushProjection(IProjection projection)
+ {
+ AddLastProjection();
+ lastProjection = projection;
+ }
+
+ /// <summary>
+ /// Create the ProjectionList and return to the query
+ /// </summary>
+ public R EndSelect
+ {
+ get
+ {
+ AddLastProjection();
+ criteria.Select(projectionList);
+ return fluentReturn;
+ }
+ }
+
+ /// <summary>
+ /// Create an alias for the previous projection
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> WithAlias(Expression<Func<object>> alias)
+ {
+ string aliasContainer = ExpressionProcessor.FindMemberExpression(alias.Body);
+ lastProjection = Projections.Alias(lastProjection, aliasContainer);
+ return this;
+ }
+
+ /// <summary>
+ /// Select an arbitrary projection
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> Select(IProjection projection)
+ {
+ PushProjection(projection);
+ return this;
+ }
+
+ /// <summary>
+ /// A property average value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectAvg(Expression<Func<T, object>> expression)
+ {
+ PushProjection(Projections.Avg(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A property average value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectAvg(Expression<Func<object>> expression)
+ {
+ PushProjection(Projections.Avg(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A property value count
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectCount(Expression<Func<T, object>> expression)
+ {
+ PushProjection(Projections.Count(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A property value count
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectCount(Expression<Func<object>> expression)
+ {
+ PushProjection(Projections.Count(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A distinct property value count
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectCountDistinct(Expression<Func<T, object>> expression)
+ {
+ PushProjection(Projections.CountDistinct(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A distinct property value count
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectCountDistinct(Expression<Func<object>> expression)
+ {
+ PushProjection(Projections.CountDistinct(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A grouping property value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectGroup(Expression<Func<T, object>> expression)
+ {
+ PushProjection(Projections.Group(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A grouping property value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectGroup(Expression<Func<object>> expression)
+ {
+ PushProjection(Projections.Group(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A property maximum value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectMax(Expression<Func<T, object>> expression)
+ {
+ PushProjection(Projections.Max(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A property maximum value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectMax(Expression<Func<object>> expression)
+ {
+ PushProjection(Projections.Max(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A property minimum value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectMin(Expression<Func<T, object>> expression)
+ {
+ PushProjection(Projections.Min(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A property minimum value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectMin(Expression<Func<object>> expression)
+ {
+ PushProjection(Projections.Min(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A projected property value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> Select(Expression<Func<T, object>> expression)
+ {
+ PushProjection(Projections.Property(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A projected property value
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> Select(Expression<Func<object>> expression)
+ {
+ PushProjection(Projections.Property(expression));
+ return this;
+ }
+
+ public QueryOverProjectionBuilder<R, T> SelectSubQuery<U>(QueryOver<U> detachedQueryOver)
+ {
+ PushProjection(Projections.SubQuery(detachedQueryOver));
+ return this;
+ }
+
+ /// <summary>
+ /// A property value sum
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectSum(Expression<Func<T, object>> expression)
+ {
+ PushProjection(Projections.Sum(expression));
+ return this;
+ }
+
+ /// <summary>
+ /// A property value sum
+ /// </summary>
+ public QueryOverProjectionBuilder<R, T> SelectSum(Expression<Func<object>> expression)
+ {
+ PushProjection(Projections.Sum(expression));
+ return this;
+ }
+
+ }
+
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-23 18:00:21 UTC (rev 4856)
+++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2009-11-25 18:36:07 UTC (rev 4857)
@@ -370,7 +370,7 @@
/// <summary>
/// A grouping property value
/// </summary>
- public static PropertyProjection GroupProperty<T>(Expression<Func<T, object>> expression)
+ public static PropertyProjection Group<T>(Expression<Func<T, object>> expression)
{
return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body));
}
@@ -378,7 +378,7 @@
/// <summary>
/// A grouping property value
/// </summary>
- public static PropertyProjection GroupProperty(Expression<Func<object>> expression)
+ public static PropertyProjection Group(Expression<Func<object>> expression)
{
return Projections.GroupProperty(ExpressionProcessor.FindMemberExpression(expression.Body));
}
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-23 18:00:21 UTC (rev 4856)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-25 18:36:07 UTC (rev 4857)
@@ -171,6 +171,11 @@
return this;
}
+ QueryOverProjectionBuilder<QueryOver<T>, T> SelectList
+ {
+ get { return new QueryOverProjectionBuilder<QueryOver<T>, T>(this, this); }
+ }
+
public QueryOverOrderBuilder<T> OrderBy(Expression<Func<T, object>> path)
{
return new QueryOverOrderBuilder<T>(this, path);
@@ -558,6 +563,9 @@
IQueryOver<T> IQueryOver<T>.Select(params IProjection[] projections)
{ return Select(projections); }
+ QueryOverProjectionBuilder<IQueryOver<T>, T> IQueryOver<T>.SelectList
+ { get { return new QueryOverProjectionBuilder<IQueryOver<T>,T>(this, this); } }
+
IQueryOverOrderBuilder<T> IQueryOver<T>.OrderBy(Expression<Func<T, object>> path)
{ return new IQueryOverOrderBuilder<T>(this, path); }
Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-23 18:00:21 UTC (rev 4856)
+++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2009-11-25 18:36:07 UTC (rev 4857)
@@ -137,6 +137,11 @@
IQueryOver<T> Select(params IProjection[] projections);
/// <summary>
+ /// Create a list of projections inline
+ /// </summary>
+ QueryOverProjectionBuilder<IQueryOver<T>, T> SelectList { get; }
+
+ /// <summary>
/// Add order expressed as a lambda expression
/// </summary>
/// <param name="path">Lambda expression</param>
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-23 18:00:21 UTC (rev 4856)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-25 18:36:07 UTC (rev 4857)
@@ -512,6 +512,7 @@
<Compile Include="Criterion\Lambda\QueryOverJoinBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverLockBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverOrderBuilder.cs" />
+ <Compile Include="Criterion\Lambda\QueryOverProjectionBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverRestrictionBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverSubqueryBuilder.cs" />
<Compile Include="Criterion\Lambda\QueryOverSubqueryPropertyBuilder.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-23 18:00:21 UTC (rev 4856)
+++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2009-11-25 18:36:07 UTC (rev 4857)
@@ -70,8 +70,8 @@
.Add(Projections.Count(() => personAlias.Age))
.Add(Projections.CountDistinct<Person>(p => p.Age))
.Add(Projections.CountDistinct(() => personAlias.Age))
- .Add(Projections.GroupProperty<Person>(p => p.Age))
- .Add(Projections.GroupProperty(() => personAlias.Age))
+ .Add(Projections.Group<Person>(p => p.Age))
+ .Add(Projections.Group(() => personAlias.Age))
.Add(Projections.Max<Person>(p => p.Age))
.Add(Projections.Max(() => personAlias.Age))
.Add(Projections.Min<Person>(p => p.Age))
@@ -85,6 +85,59 @@
AssertCriteriaAreEqual(expected, actual);
}
+ [Test]
+ public void InlineProjectionList()
+ {
+ ICriteria expected =
+ CreateTestCriteria(typeof(Person), "personAlias")
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.Alias(Projections.Avg("Age"), "personAgeProjectionAlias"))
+ .Add(Projections.Avg("Age"))
+ .Add(Projections.Avg("personAlias.Age"))
+ .Add(Projections.Count("Age"))
+ .Add(Projections.Count("personAlias.Age"))
+ .Add(Projections.CountDistinct("Age"))
+ .Add(Projections.CountDistinct("personAlias.Age"))
+ .Add(Projections.GroupProperty("Age"))
+ .Add(Projections.GroupProperty("personAlias.Age"))
+ .Add(Projections.Max("Age"))
+ .Add(Projections.Max("personAlias.Age"))
+ .Add(Projections.Min("Age"))
+ .Add(Projections.Min("personAlias.Age"))
+ .Add(Projections.Property("Age"))
+ .Add(Projections.Property("personAlias.Age"))
+ .Add(Projections.SubQuery(DetachedCriteriaAge))
+ .Add(Projections.Sum("Age"))
+ .Add(Projections.Sum("personAlias.Age")));
+
+ Person personAlias = null;
+ Person personAgeProjectionAlias = null;
+ var actual =
+ CreateTestQueryOver<Person>(() => personAlias)
+ .SelectList
+ .SelectAvg(p => p.Age).WithAlias(() => personAgeProjectionAlias)
+ .Select(Projections.Avg("Age")) // allows private properties
+ .SelectAvg(() => personAlias.Age)
+ .SelectCount(p => p.Age)
+ .SelectCount(() => personAlias.Age)
+ .SelectCountDistinct(p => p.Age)
+ .SelectCountDistinct(() => personAlias.Age)
+ .SelectGroup(p => p.Age)
+ .SelectGroup(() => personAlias.Age)
+ .SelectMax(p => p.Age)
+ .SelectMax(() => personAlias.Age)
+ .SelectMin(p => p.Age)
+ .SelectMin(() => personAlias.Age)
+ .Select(p => p.Age)
+ .Select(() => personAlias.Age)
+ .SelectSubQuery(DetachedQueryOverAge)
+ .SelectSum(p => p.Age)
+ .SelectSum(() => personAlias.Age)
+ .EndSelect;
+
+ AssertCriteriaAreEqual(expected, actual);
+ }
+
}
}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ste...@us...> - 2009-11-27 20:10:59
|
Revision: 4861
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4861&view=rev
Author: steverstrong
Date: 2009-11-27 20:10:47 +0000 (Fri, 27 Nov 2009)
Log Message:
-----------
Further Linq test cases added, and various related bugs fixed
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs
trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs
trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs
trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs
trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs
trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs
trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs
trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs
trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs
trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs
trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate.Test/Linq/ProjectionsTests.cs
trunk/nhibernate/src/NHibernate.Test/Linq/PropertyMethodMappingTests.cs
trunk/nhibernate/src/NHibernate.Test/Linq/QueryReuseTests.cs
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeBuilder.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -261,9 +261,9 @@
return new HqlBitwiseNot(_factory);
}
- public HqlNot Not(HqlBooleanExpression operand)
+ public HqlBooleanNot Not(HqlBooleanExpression operand)
{
- return new HqlNot(_factory, operand);
+ return new HqlBooleanNot(_factory, operand);
}
public HqlAverage Average(HqlExpression expression)
@@ -360,5 +360,16 @@
{
return new HqlDistinctHolder(_factory, children);
}
+
+ public HqlIsNull IsNull(HqlExpression lhs)
+ {
+ return new HqlIsNull(_factory, lhs);
+ }
+
+ public HqlIsNotNull IsNotNull(HqlExpression lhs)
+ {
+ return new HqlIsNotNull(_factory, lhs);
+ }
}
+
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Hql/Ast/HqlTreeNode.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -192,6 +192,9 @@
case TypeCode.Int32:
SetText("integer");
break;
+ case TypeCode.Int64:
+ SetText("long");
+ break;
case TypeCode.Decimal:
SetText("decimal");
break;
@@ -201,6 +204,9 @@
case TypeCode.String:
SetText("string");
break;
+ case TypeCode.Double:
+ SetText("double");
+ break;
default:
if (type == typeof(Guid))
{
@@ -299,7 +305,7 @@
public class HqlBooleanAnd : HqlBooleanExpression
{
public HqlBooleanAnd(IASTFactory factory, HqlBooleanExpression lhs, HqlBooleanExpression rhs)
- : base(HqlSqlWalker.AND, "/", factory, lhs, rhs)
+ : base(HqlSqlWalker.AND, "and", factory, lhs, rhs)
{
}
}
@@ -576,9 +582,9 @@
}
}
- public class HqlNot : HqlBooleanExpression
+ public class HqlBooleanNot : HqlBooleanExpression
{
- public HqlNot(IASTFactory factory, HqlBooleanExpression operand)
+ public HqlBooleanNot(IASTFactory factory, HqlBooleanExpression operand)
: base(HqlSqlWalker.NOT, "not", factory, operand)
{
}
@@ -712,4 +718,19 @@
{
}
}
+
+ public class HqlIsNull : HqlBooleanExpression
+ {
+ public HqlIsNull(IASTFactory factory, HqlExpression lhs)
+ : base(HqlSqlWalker.IS_NULL, "is null", factory, lhs)
+ {
+ }
+ }
+
+ public class HqlIsNotNull : HqlBooleanExpression
+ {
+ public HqlIsNotNull(IASTFactory factory, HqlExpression lhs) : base(HqlSqlWalker.IS_NOT_NULL, "is not null", factory, lhs)
+ {
+ }
+ }
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -336,11 +336,14 @@
throw new ArgumentNullException("val",
"A type specific Set(name, val) should be called because the Type can not be guessed from a null value.");
}
- }
+
+ SetParameter(name, val, type);
+ }
else
{
SetParameter(name, val, DetermineType(name, val));
}
+
return this;
}
Modified: trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/ExpressionToHqlTranslationResults.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -3,6 +3,7 @@
using System.Linq;
using System.Linq.Expressions;
using NHibernate.Hql.Ast;
+using NHibernate.Type;
namespace NHibernate.Linq
{
@@ -10,9 +11,9 @@
{
public HqlQuery Statement { get; private set; }
public ResultTransformer ResultTransformer { get; private set; }
- public List<Action<IQuery, IDictionary<string, object>>> AdditionalCriteria { get; private set; }
+ public List<Action<IQuery, IDictionary<string, Pair<object, IType>>>> AdditionalCriteria { get; private set; }
- public ExpressionToHqlTranslationResults(HqlQuery statement, IList<LambdaExpression> itemTransformers, IList<LambdaExpression> listTransformers, List<Action<IQuery, IDictionary<string, object>>> additionalCriteria)
+ public ExpressionToHqlTranslationResults(HqlQuery statement, IList<LambdaExpression> itemTransformers, IList<LambdaExpression> listTransformers, List<Action<IQuery, IDictionary<string, Pair<object, IType>>>> additionalCriteria)
{
Statement = statement;
Modified: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhAverageExpression.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -1,11 +1,37 @@
-using System.Linq.Expressions;
+using System;
+using System.Linq.Expressions;
namespace NHibernate.Linq.Expressions
{
public class NhAverageExpression : NhAggregatedExpression
{
- public NhAverageExpression(Expression expression) : base(expression, NhExpressionType.Average)
+ public NhAverageExpression(Expression expression) : base(expression, CalculateAverageType(expression.Type), NhExpressionType.Average)
{
}
+
+ private static System.Type CalculateAverageType(System.Type inputType)
+ {
+ bool isNullable = false;
+
+ if (inputType.IsNullable())
+ {
+ isNullable = true;
+ inputType = inputType.NullableOf();
+ }
+
+ switch (System.Type.GetTypeCode(inputType))
+ {
+ case TypeCode.Int16:
+ case TypeCode.Int32:
+ case TypeCode.Int64:
+ case TypeCode.Single:
+ case TypeCode.Double:
+ return isNullable ? typeof(double?) : typeof (double);
+ case TypeCode.Decimal:
+ return isNullable ? typeof(decimal?) : typeof(decimal);
+ }
+
+ throw new NotSupportedException(inputType.FullName);
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/Expressions/NhCountExpression.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -4,9 +4,25 @@
{
public class NhCountExpression : NhAggregatedExpression
{
- public NhCountExpression(Expression expression)
- : base(expression, typeof(int), NhExpressionType.Count)
+ public NhCountExpression(Expression expression, System.Type type)
+ : base(expression, type, NhExpressionType.Count)
{
}
}
-}
\ No newline at end of file
+
+ public class NhShortCountExpression : NhCountExpression
+ {
+ public NhShortCountExpression(Expression expression)
+ : base(expression, typeof(int))
+ {
+ }
+ }
+
+ public class NhLongCountExpression : NhCountExpression
+ {
+ public NhLongCountExpression(Expression expression)
+ : base(expression, typeof(long))
+ {
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/LinqExtensionMethods.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -24,5 +24,10 @@
return (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>));
}
+ public static System.Type NullableOf(this System.Type type)
+ {
+ return type.GetGenericArguments()[0];
+ }
+
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/NamedParameter.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -1,3 +1,6 @@
+using System;
+using NHibernate.Type;
+
namespace NHibernate.Linq
{
public class NamedParameter
@@ -2,10 +5,12 @@
{
- public NamedParameter(string name, object value)
+ public NamedParameter(string name, object value, IType type)
{
Name = name;
Value = value;
+ Type = type;
}
- public string Name { get; set; }
- public object Value { get; set; }
+ public string Name { get; private set; }
+ public object Value { get; internal set; }
+ public IType Type { get; internal set; }
}
Modified: trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/NhLinqExpression.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -6,6 +6,7 @@
using NHibernate.Hql.Ast.ANTLR.Tree;
using NHibernate.Linq.ResultOperators;
using NHibernate.Linq.Visitors;
+using NHibernate.Type;
using Remotion.Data.Linq;
using Remotion.Data.Linq.Clauses;
using Remotion.Data.Linq.Clauses.StreamedData;
@@ -25,7 +26,7 @@
public NhLinqExpressionReturnType ReturnType { get; private set; }
- public IDictionary<string, object> ParameterValuesByName { get; private set; }
+ public IDictionary<string, Pair<object, IType>> ParameterValuesByName { get; private set; }
public ExpressionToHqlTranslationResults ExpressionToHqlTranslationResults { get; private set; }
@@ -40,7 +41,10 @@
_constantToParameterMap = ExpressionParameterVisitor.Visit(_expression);
- ParameterValuesByName = _constantToParameterMap.Values.ToDictionary(p => p.Name, p => p.Value);
+ ParameterValuesByName = _constantToParameterMap.Values.ToDictionary(p => p.Name,
+ p =>
+ new Pair<object, IType>
+ {Left = p.Value, Right = p.Type});
Key = ExpressionKeyVisitor.Visit(_expression, _constantToParameterMap);
Modified: trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/NhQueryProvider.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -3,6 +3,7 @@
using System.Linq;
using System.Linq.Expressions;
using NHibernate.Impl;
+using NHibernate.Type;
namespace NHibernate.Linq
{
@@ -51,15 +52,23 @@
return new NhQueryable<T>(this, expression);
}
- static void SetParameters(IQuery query, IDictionary<string, object> parameters)
+ static void SetParameters(IQuery query, IDictionary<string, Pair<object, IType>> parameters)
{
foreach (var parameterName in query.NamedParameters)
{
- query.SetParameter(parameterName, parameters[parameterName]);
+ var param = parameters[parameterName];
+ if (param.Left == null)
+ {
+ query.SetParameter(parameterName, param.Left, param.Right);
+ }
+ else
+ {
+ query.SetParameter(parameterName, param.Left);
+ }
}
}
- public void SetResultTransformerAndAdditionalCriteria(IQuery query, IDictionary<string, object> parameters)
+ public void SetResultTransformerAndAdditionalCriteria(IQuery query, IDictionary<string, Pair<object, IType>> parameters)
{
var queryImpl = (ExpressionQueryImpl) query;
@@ -73,4 +82,10 @@
}
}
}
+
+ public class Pair<TLeft, TRight>
+ {
+ public TLeft Left { get; set; }
+ public TRight Right { get; set; }
+ }
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/ParameterAggregator.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using NHibernate.Type;
namespace NHibernate.Linq
{
@@ -6,9 +7,9 @@
{
private readonly List<NamedParameter> _parameters = new List<NamedParameter>();
- public NamedParameter AddParameter(object value)
+ public NamedParameter AddParameter(object value, IType type)
{
- var parameter = new NamedParameter("p" + (_parameters.Count + 1), value);
+ var parameter = new NamedParameter("p" + (_parameters.Count + 1), value, type);
_parameters.Add(parameter);
return parameter;
}
Modified: trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/ReWriters/MergeAggregatingResultsRewriter.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -53,9 +53,14 @@
}
else if (resultOperator is CountResultOperator)
{
- queryModel.SelectClause.Selector = new NhCountExpression(queryModel.SelectClause.Selector);
+ queryModel.SelectClause.Selector = new NhShortCountExpression(queryModel.SelectClause.Selector);
queryModel.ResultOperators.Remove(resultOperator);
}
+ else if (resultOperator is LongCountResultOperator)
+ {
+ queryModel.SelectClause.Selector = new NhLongCountExpression(queryModel.SelectClause.Selector);
+ queryModel.ResultOperators.Remove(resultOperator);
+ }
base.VisitResultOperator(resultOperator, queryModel, index);
}
@@ -89,7 +94,7 @@
{
case "Count":
return CreateAggregate(m.Arguments[0], (LambdaExpression)m.Arguments[1],
- e => new NhCountExpression(e));
+ e => new NhShortCountExpression(e));
case "Min":
return CreateAggregate(m.Arguments[0], (LambdaExpression) m.Arguments[1],
e => new NhMinExpression(e));
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -25,7 +25,7 @@
{
if (!typeof(IQueryable).IsAssignableFrom(expression.Type))
{
- _parameters.Add(expression, new NamedParameter("p" + (_parameters.Count + 1), expression.Value));
+ _parameters.Add(expression, new NamedParameter("p" + (_parameters.Count + 1), expression.Value, NHibernateUtil.GuessType(expression.Type)));
}
return base.VisitConstantExpression(expression);
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -201,8 +201,31 @@
_hqlTreeBuilder.Case(
new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(1)) },
_hqlTreeBuilder.Constant(0));
+
+ return _hqlTreeBuilder.Equality(lhs, rhs);
}
+ // Also check for nullability
+ if (expression.Left.Type.IsNullable() || expression.Right.Type.IsNullable())
+ {
+ // TODO - yuck. This clone is needed because the AST tree nodes are not immutable,
+ // and sharing nodes between multiple branches will cause issues in the hqlSqlWalker phase -
+ // a node, x, gets visited during the walk and updated to refer to a real property. Later in
+ // the walk, x get revisited (since we copied it here), but now the type doesn't match what
+ // the parser expects. So we can't share. Implementing Clone() on HqlTreeNode would be better
+ // that doing a full visit of the Expression tree. Allowing shared nodes in the AST would be better
+ // still, but might be more work
+ var lhs2 = VisitExpression(expression.Left).AsExpression();
+ var rhs2 = VisitExpression(expression.Right).AsExpression();
+
+ return _hqlTreeBuilder.BooleanOr(
+ _hqlTreeBuilder.BooleanAnd(
+ _hqlTreeBuilder.IsNull(lhs),
+ _hqlTreeBuilder.IsNull(rhs)),
+ _hqlTreeBuilder.Equality(lhs2, rhs2)
+ );
+ }
+
return _hqlTreeBuilder.Equality(lhs, rhs);
case ExpressionType.NotEqual:
@@ -218,8 +241,32 @@
_hqlTreeBuilder.Case(
new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(1)) },
_hqlTreeBuilder.Constant(0));
+
+ return _hqlTreeBuilder.Inequality(lhs, rhs);
+
}
+ // Also check for nullability
+ if (expression.Left.Type.IsNullable() || expression.Right.Type.IsNullable())
+ {
+ var lhs2 = VisitExpression(expression.Left).AsExpression();
+ var rhs2 = VisitExpression(expression.Right).AsExpression();
+ var lhs3 = VisitExpression(expression.Left).AsExpression();
+ var rhs3 = VisitExpression(expression.Right).AsExpression();
+
+ return
+ _hqlTreeBuilder.BooleanOr(
+ _hqlTreeBuilder.BooleanOr(
+ _hqlTreeBuilder.BooleanAnd(
+ _hqlTreeBuilder.IsNull(lhs),
+ _hqlTreeBuilder.IsNotNull(rhs)),
+ _hqlTreeBuilder.BooleanAnd(
+ _hqlTreeBuilder.IsNotNull(lhs2),
+ _hqlTreeBuilder.IsNull(rhs2))
+ ),
+ _hqlTreeBuilder.Inequality(lhs3, rhs3));
+ }
+
return _hqlTreeBuilder.Inequality(lhs, rhs);
case ExpressionType.And:
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/NhExpressionTreeVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -69,7 +69,7 @@
{
Expression nx = base.VisitExpression(expression.Expression);
- return nx != expression.Expression ? new NhCountExpression(nx) : expression;
+ return nx != expression.Expression ? new NhShortCountExpression(nx) : expression;
}
protected virtual Expression VisitNhSum(NhSumExpression expression)
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/NhThrowingExpressionTreeVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -85,7 +85,7 @@
{
Expression nx = base.VisitExpression(expression.Expression);
- return nx != expression.Expression ? new NhCountExpression(nx) : expression;
+ return nx != expression.Expression ? new NhCountExpression(nx, expression.Type) : expression;
}
protected virtual Expression BaseVisitNhSum(NhSumExpression expression)
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/QueryModelVisitor.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -9,6 +9,7 @@
using NHibernate.Linq.GroupJoin;
using NHibernate.Linq.ResultOperators;
using NHibernate.Linq.ReWriters;
+using NHibernate.Type;
using Remotion.Data.Linq;
using Remotion.Data.Linq.Clauses;
using Remotion.Data.Linq.Clauses.Expressions;
@@ -49,7 +50,7 @@
private readonly HqlTreeBuilder _hqlTreeBuilder;
- private readonly List<Action<IQuery, IDictionary<string, object>>> _additionalCriteria = new List<Action<IQuery, IDictionary<string, object>>>();
+ private readonly List<Action<IQuery, IDictionary<string, Pair<object, IType>>>> _additionalCriteria = new List<Action<IQuery, IDictionary<string, Pair<object, IType>>>>();
private readonly List<LambdaExpression> _listTransformers = new List<LambdaExpression>();
private readonly List<LambdaExpression> _itemTransformers = new List<LambdaExpression>();
@@ -200,6 +201,10 @@
{
ProcessGroupByOperator((GroupResultOperator)resultOperator);
}
+ else if (resultOperator is SingleResultOperator)
+ {
+ ProcessSingleOperator((SingleResultOperator) resultOperator);
+ }
else
{
throw new NotSupportedException(string.Format("The {0} result operator is not current supported",
@@ -207,6 +212,23 @@
}
}
+ private void ProcessSingleOperator(SingleResultOperator resultOperator)
+ {
+ Expression<Func<IEnumerable<object>, object>> lambda;
+
+ if (resultOperator.ReturnDefaultWhenEmpty)
+ {
+ lambda = (IEnumerable<object> list) => list.SingleOrDefault();
+ }
+ else
+ {
+ lambda = (IEnumerable<object> list) => list.Single();
+ }
+
+ _additionalCriteria.Add((q, p) => q.SetMaxResults(1));
+ _listTransformers.Add(lambda);
+ }
+
private void ProcessClientSideResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel)
{
if (resultOperator is NonAggregatingGroupBy)
@@ -307,7 +329,7 @@
// clause to see if it is valid
if (_parameters.TryGetValue(resultOperator.Count as ConstantExpression, out parameterName))
{
- _additionalCriteria.Add((q, p) => q.SetMaxResults((int) p[parameterName.Name]));
+ _additionalCriteria.Add((q, p) => q.SetMaxResults((int) p[parameterName.Name].Left));
}
else
{
@@ -321,7 +343,7 @@
if (_parameters.TryGetValue(resultOperator.Count as ConstantExpression, out parameterName))
{
- _additionalCriteria.Add((q, p) => q.SetFirstResult((int)p[parameterName.Name]));
+ _additionalCriteria.Add((q, p) => q.SetFirstResult((int)p[parameterName.Name].Left));
}
else
{
@@ -389,19 +411,6 @@
_listTransformers.Add(lambdaExpr);
return;
- /*
- _listTransformers.Add(Expression.Lambda(
- Expression.Call(toList,
- Expression.Call(groupByMethod,
- Expression.Call(castToItem,
- Expression.Call(selectObject,
- Expression.Call(
- castToObjectArray,
- listParameter),
- index)),
- keySelectorExpr)
- ),
- listParameter));*/
}
private static System.Type SourceOf(Expression keySelector)
Modified: trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/LinqTestCase.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -3538,7 +3538,7 @@
orderLine = new OrderLine { Order = orders.Where(o => o.OrderId == 11077 ).First(), Product = products.Where(p => p.Name == "Original Frankfurter grüne Soße").First(), UnitPrice = 13.00M, Quantity = 2, Discount = 0M }; session.Insert(orderLine);
}
- protected override void OnFixtureSetup()
+ protected override void OnFixtureSetup()
{
CreateTestData();
}
Modified: trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs 2009-11-27 18:12:00 UTC (rev 4860)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/ParameterisedQueries.cs 2009-11-27 20:10:47 UTC (rev 4861)
@@ -50,8 +50,8 @@
Assert.AreEqual(nhLondon.Key, nhNewYork.Key);
Assert.AreEqual(1, nhLondon.ParameterValuesByName.Count);
Assert.AreEqual(1, nhNewYork.ParameterValuesByName.Count);
- Assert.AreEqual("London", nhLondon.ParameterValuesByName.First().Value);
- Assert.AreEqual("New York", nhNewYork.ParameterValuesByName.First().Value);
+ Assert.AreEqual("London", nhLondon.ParameterValuesByName.First().Value.Left);
+ Assert.AreEqual("New York", nhNewYork.ParameterValuesByName.First().Value.Left);
}
}
Added: trunk/nhibernate/src/NHibernate.Test/Linq/ProjectionsTests.cs
===================================================...
[truncated message content] |
|
From: <fab...@us...> - 2009-11-28 12:00:53
|
Revision: 4862
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4862&view=rev
Author: fabiomaulo
Date: 2009-11-28 12:00:44 +0000 (Sat, 28 Nov 2009)
Log Message:
-----------
- Starting refactoring of binders
- bug fixed for <meta> (the default inherit is true)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmMapping.cs
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/Binder.cs
trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs
trunk/nhibernate/src/NHibernate/NHibernate.csproj
trunk/nhibernate/src/NHibernate.Test/MappingTest/NonReflectiveBinderFixture.cs
trunk/nhibernate/src/NHibernate.Test/MappingTest/Wicked.hbm.xml
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/IEntityMetadata.cs
Modified: trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmMapping.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmMapping.cs 2009-11-27 20:10:47 UTC (rev 4861)
+++ trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmMapping.cs 2009-11-28 12:00:44 UTC (rev 4862)
@@ -1,3 +1,5 @@
+using System.Linq;
+
namespace NHibernate.Cfg.MappingSchema
{
partial class HbmMapping : AbstractDecoratable
@@ -16,5 +18,25 @@
{
return meta;
}
+
+ public HbmClass[] RootClasses
+ {
+ get { return Items != null ? Items.OfType<HbmClass>().ToArray():new HbmClass[0]; }
+ }
+
+ public HbmSubclass[] SubClasses
+ {
+ get { return Items != null ? Items.OfType<HbmSubclass>().ToArray(): new HbmSubclass[0]; }
+ }
+
+ public HbmJoinedSubclass[] JoinedSubclasses
+ {
+ get { return Items != null ? Items.OfType<HbmJoinedSubclass>().ToArray(): new HbmJoinedSubclass[0]; }
+ }
+
+ public HbmUnionSubclass[] UnionSubclasses
+ {
+ get { return Items != null ? Items.OfType<HbmUnionSubclass>().ToArray(): new HbmUnionSubclass[0]; }
+ }
}
}
\ No newline at end of file
Added: trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/IEntityMetadata.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/IEntityMetadata.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/IEntityMetadata.cs 2009-11-28 12:00:44 UTC (rev 4862)
@@ -0,0 +1,7 @@
+namespace NHibernate.Cfg.MappingSchema
+{
+ public interface IEntityMetadata
+ {
+
+ }
+}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/Binder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/Binder.cs 2009-11-27 20:10:47 UTC (rev 4861)
+++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/Binder.cs 2009-11-28 12:00:44 UTC (rev 4862)
@@ -142,6 +142,24 @@
return (T) new XmlSerializer(typeof (T)).Deserialize(reader);
}
+ protected static XmlNode Serialize<T>(T hbmElement)
+ {
+ // TODO : this method is only for TEMPORAL usage; should be removed after refactorize all binders
+ var serializer = new XmlSerializer(typeof (T));
+ using (var memStream = new MemoryStream(2000))
+ using (var xmlWriter = XmlWriter.Create(memStream))
+ {
+ serializer.Serialize(xmlWriter, hbmElement);
+ memStream.Position = 0;
+ using (XmlReader reader = XmlReader.Create(memStream))
+ {
+ var hbmDocument = new XmlDocument();
+ hbmDocument.Load(reader);
+ return hbmDocument.DocumentElement;
+ }
+ }
+ }
+
protected static string GetXmlEnumAttribute(Enum cascadeStyle)
{
MemberInfo[] memberInfo = cascadeStyle.GetType().GetMember(cascadeStyle.ToString());
@@ -231,7 +249,7 @@
continue;
}
var inheritableValue = GetAttributeValue(metaNode, "inherit");
- bool inheritable = inheritableValue != null ? IsTrue(inheritableValue) : false;
+ bool inheritable = inheritableValue != null ? IsTrue(inheritableValue) : true;
if (onlyInheritable & !inheritable)
{
continue;
Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs 2009-11-27 20:10:47 UTC (rev 4861)
+++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/MappingRootBinder.cs 2009-11-28 12:00:44 UTC (rev 4862)
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Xml;
@@ -32,10 +33,7 @@
AddFilterDefinitions(mappingSchema);
AddTypeDefs(mappingSchema);
- AddRootClasses(node, inheritedMetas);
- AddSubclasses(node, inheritedMetas);
- AddJoinedSubclasses(node, inheritedMetas);
- AddUnionSubclasses(node, inheritedMetas);
+ AddEntitiesMappings(node, mappingSchema, inheritedMetas);
AddQueries(mappingSchema);
AddSqlQueries(mappingSchema);
@@ -44,6 +42,26 @@
AddResultSetMappingDefinitions(mappingSchema);
}
+ private void AddEntitiesMappings(XmlNode node, HbmMapping mappingSchema, IDictionary<string, MetaAttribute> inheritedMetas)
+ {
+ foreach (var rootClass in mappingSchema.RootClasses)
+ {
+ AddRootClasses(Serialize(rootClass), rootClass, inheritedMetas);
+ }
+ foreach (var subclass in mappingSchema.SubClasses)
+ {
+ AddSubclasses(Serialize(subclass), subclass, inheritedMetas);
+ }
+ foreach (var joinedSubclass in mappingSchema.JoinedSubclasses)
+ {
+ AddJoinedSubclasses(Serialize(joinedSubclass), joinedSubclass, inheritedMetas);
+ }
+ foreach (var unionSubclass in mappingSchema.UnionSubclasses)
+ {
+ AddUnionSubclasses(Serialize(unionSubclass), unionSubclass, inheritedMetas);
+ }
+ }
+
private void SetMappingsProperties(HbmMapping mappingSchema)
{
mappings.SchemaName = mappingSchema.schema;
@@ -65,36 +83,32 @@
}
}
- private void AddRootClasses(XmlNode parentNode, IDictionary<string, MetaAttribute> inheritedMetas)
+ private void AddRootClasses(XmlNode parentNode, HbmClass rootClass, IDictionary<string, MetaAttribute> inheritedMetas)
{
RootClassBinder binder = new RootClassBinder(this, namespaceManager, dialect);
- foreach (XmlNode node in parentNode.SelectNodes(HbmConstants.nsClass, namespaceManager))
- binder.Bind(node, Deserialize<HbmClass>(node), inheritedMetas);
+ binder.Bind(parentNode, rootClass, inheritedMetas);
}
- private void AddUnionSubclasses(XmlNode parentNode, IDictionary<string, MetaAttribute> inheritedMetas)
+ private void AddUnionSubclasses(XmlNode parentNode, HbmUnionSubclass unionSubclass, IDictionary<string, MetaAttribute> inheritedMetas)
{
UnionSubclassBinder binder = new UnionSubclassBinder(this, namespaceManager, dialect);
- foreach (XmlNode node in parentNode.SelectNodes(HbmConstants.nsUnionSubclass, namespaceManager))
- binder.Bind(node, inheritedMetas);
+ binder.Bind(parentNode, inheritedMetas);
}
- private void AddJoinedSubclasses(XmlNode parentNode, IDictionary<string, MetaAttribute> inheritedMetas)
+ private void AddJoinedSubclasses(XmlNode parentNode, HbmJoinedSubclass joinedSubclass, IDictionary<string, MetaAttribute> inheritedMetas)
{
JoinedSubclassBinder binder = new JoinedSubclassBinder(this, namespaceManager, dialect);
- foreach (XmlNode node in parentNode.SelectNodes(HbmConstants.nsJoinedSubclass, namespaceManager))
- binder.Bind(node, inheritedMetas);
+ binder.Bind(parentNode, inheritedMetas);
}
- private void AddSubclasses(XmlNode parentNode, IDictionary<string, MetaAttribute> inheritedMetas)
+ private void AddSubclasses(XmlNode parentNode, HbmSubclass subClass, IDictionary<string, MetaAttribute> inheritedMetas)
{
SubclassBinder binder = new SubclassBinder(this, namespaceManager, dialect);
- foreach (XmlNode node in parentNode.SelectNodes(HbmConstants.nsSubclass, namespaceManager))
- binder.Bind(node, inheritedMetas);
+ binder.Bind(parentNode, inheritedMetas);
}
private void AddQueries(HbmMapping mappingSchema)
Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-27 20:10:47 UTC (rev 4861)
+++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2009-11-28 12:00:44 UTC (rev 4862)
@@ -495,6 +495,7 @@
<Compile Include="Cfg\Loquacious\MappingsConfiguration.cs" />
<Compile Include="Cfg\Loquacious\ProxyConfiguration.cs" />
<Compile Include="Cfg\MappingSchema\HbmDefinition.cs" />
+ <Compile Include="Cfg\MappingSchema\IEntityMetadata.cs" />
<Compile Include="Cfg\SchemaAutoAction.cs" />
<Compile Include="Cfg\SessionFactoryConfigurationBase.cs" />
<Compile Include="Cfg\ISessionFactoryConfiguration.cs" />
Modified: trunk/nhibernate/src/NHibernate.Test/MappingTest/NonReflectiveBinderFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MappingTest/NonReflectiveBinderFixture.cs 2009-11-27 20:10:47 UTC (rev 4861)
+++ trunk/nhibernate/src/NHibernate.Test/MappingTest/NonReflectiveBinderFixture.cs 2009-11-28 12:00:44 UTC (rev 4862)
@@ -157,7 +157,7 @@
Assert.That(propertyAttribute.Value, Is.EqualTo("monetaryamount anotherSet composite property empinone level"));
}
- [Test]
+ [Test, Ignore("Not fixed, see the TODO of this test.")]
public void Comparator()
{
PersistentClass cm = cfg.GetClassMapping("NHibernate.Test.MappingTest.Wicked");
Modified: trunk/nhibernate/src/NHibernate.Test/MappingTest/Wicked.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/MappingTest/Wicked.hbm.xml 2009-11-27 20:10:47 UTC (rev 4861)
+++ trunk/nhibernate/src/NHibernate.Test/MappingTest/Wicked.hbm.xml 2009-11-28 12:00:44 UTC (rev 4862)
@@ -30,7 +30,8 @@
</property>
</component>
- <set name="SortedEmployee" sort="NonExistingComparator">
+ <!--<set name="SortedEmployee" sort="NonExistingComparator">-->
+ <set name="SortedEmployee">
<meta attribute="globalmutated">sortedemployee level</meta>
<key column="attrb_id"/>
<many-to-many class="Employee" column="id"/>
@@ -71,7 +72,7 @@
<property name="Pregnant"/>
<property name="Birthdate" type="Date"/>
<subclass name="DomesticAnimal">
- <meta attribute="Auditable"/>
+ <meta attribute="Auditable" inherit="true"/>
<property name="Name"/>
<many-to-one name="Owner"/>
<subclass name="Cat"/>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2009-11-28 21:09:32
|
Revision: 4868
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4868&view=rev
Author: ricbrown
Date: 2009-11-28 21:09:24 +0000 (Sat, 28 Nov 2009)
Log Message:
-----------
Expanded IQueryOver to maintain both the original, and sub-criteria types.
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverFetchBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverJoinBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverLockBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs
trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
trunk/nhibernate/src/NHibernate/IQueryOver.cs
trunk/nhibernate/src/NHibernate/ISession.cs
trunk/nhibernate/src/NHibernate/Impl/SessionImpl.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/LambdaFixtureBase.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/Model.cs
trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverFetchBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverFetchBuilder.cs 2009-11-28 14:04:43 UTC (rev 4867)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverFetchBuilder.cs 2009-11-28 21:09:24 UTC (rev 4868)
@@ -9,29 +9,29 @@
namespace NHibernate.Criterion
{
- public class QueryOverFetchBuilder<T> : QueryOverFetchBuilderBase<QueryOver<T>, T>
+ public class QueryOverFetchBuilder<S,T> : QueryOverFetchBuilderBase<QueryOver<S,T>, S, T>
{
- public QueryOverFetchBuilder(QueryOver<T> root, Expression<Func<T, object>> path)
+ public QueryOverFetchBuilder(QueryOver<S,T> root, Expression<Func<S, object>> path)
: base(root, path) { }
}
- public class IQueryOverFetchBuilder<T> : QueryOverFetchBuilderBase<IQueryOver<T>, T>
+ public class IQueryOverFetchBuilder<S,T> : QueryOverFetchBuilderBase<IQueryOver<S,T>, S, T>
{
- public IQueryOverFetchBuilder(IQueryOver<T> root, Expression<Func<T, object>> path)
+ public IQueryOverFetchBuilder(IQueryOver<S,T> root, Expression<Func<S, object>> path)
: base(root, path) { }
}
- public class QueryOverFetchBuilderBase<R, T> where R : IQueryOver<T>
+ public class QueryOverFetchBuilderBase<R, S, T> where R : IQueryOver<S,T>
{
protected R root;
protected string path;
- protected QueryOverFetchBuilderBase(R root, Expression<Func<T, object>> path)
+ protected QueryOverFetchBuilderBase(R root, Expression<Func<S, object>> path)
{
this.root = root;
this.path = ExpressionProcessor.FindMemberExpression(path.Body);
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverJoinBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverJoinBuilder.cs 2009-11-28 14:04:43 UTC (rev 4867)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverJoinBuilder.cs 2009-11-28 21:09:24 UTC (rev 4868)
@@ -8,100 +8,100 @@
namespace NHibernate.Criterion.Lambda
{
-
- public class QueryOverJoinBuilder<T> : QueryOverJoinBuilderBase<QueryOver<T>, T>
+
+ public class QueryOverJoinBuilder<S,T> : QueryOverJoinBuilderBase<QueryOver<S,T>, S, T>
{
- public QueryOverJoinBuilder(QueryOver<T> root, JoinType joinType) : base(root, joinType) { }
+ public QueryOverJoinBuilder(QueryOver<S,T> root, JoinType joinType) : base(root, joinType) { }
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path)
+ public QueryOver<S,U> JoinQueryOver<U>(Expression<Func<T, U>> path)
{
return root.JoinQueryOver<U>(path, joinType);
}
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path)
+ public QueryOver<S,U> JoinQueryOver<U>(Expression<Func<U>> path)
{
return root.JoinQueryOver<U>(path, joinType);
}
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path, Expression<Func<U>> alias)
+ public QueryOver<S,U> JoinQueryOver<U>(Expression<Func<T, U>> path, Expression<Func<U>> alias)
{
return root.JoinQueryOver<U>(path, alias, joinType);
}
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias)
+ public QueryOver<S,U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias)
{
return root.JoinQueryOver<U>(path, alias, joinType);
}
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path)
+ public QueryOver<S,U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path)
{
return root.JoinQueryOver<U>(path, joinType);
}
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path)
+ public QueryOver<S,U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path)
{
return root.JoinQueryOver<U>(path, joinType);
}
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path, Expression<Func<U>> alias)
+ public QueryOver<S,U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path, Expression<Func<U>> alias)
{
return root.JoinQueryOver<U>(path, alias, joinType);
}
- public QueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias)
+ public QueryOver<S,U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias)
{
return root.JoinQueryOver<U>(path, alias, joinType);
}
}
- public class IQueryOverJoinBuilder<T> : QueryOverJoinBuilderBase<IQueryOver<T>, T>
+ public class IQueryOverJoinBuilder<S,T> : QueryOverJoinBuilderBase<IQueryOver<S,T>, S, T>
{
- public IQueryOverJoinBuilder(IQueryOver<T> root, JoinType joinType) : base(root, joinType) { }
+ public IQueryOverJoinBuilder(IQueryOver<S,T> root, JoinType joinType) : base(root, joinType) { }
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path)
+ public IQueryOver<S,U> JoinQueryOver<U>(Expression<Func<T, U>> path)
{
return root.JoinQueryOver<U>(path, joinType);
}
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path)
+ public IQueryOver<S,U> JoinQueryOver<U>(Expression<Func<U>> path)
{
return root.JoinQueryOver<U>(path, joinType);
}
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, U>> path, Expression<Func<U>> alias)
+ public IQueryOver<S,U> JoinQueryOver<U>(Expression<Func<T, U>> path, Expression<Func<U>> alias)
{
return root.JoinQueryOver<U>(path, alias, joinType);
}
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias)
+ public IQueryOver<S,U> JoinQueryOver<U>(Expression<Func<U>> path, Expression<Func<U>> alias)
{
return root.JoinQueryOver<U>(path, alias, joinType);
}
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path)
+ public IQueryOver<S,U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path)
{
return root.JoinQueryOver<U>(path, joinType);
}
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path)
+ public IQueryOver<S,U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path)
{
return root.JoinQueryOver<U>(path, joinType);
}
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path, Expression<Func<U>> alias)
+ public IQueryOver<S,U> JoinQueryOver<U>(Expression<Func<T, IEnumerable<U>>> path, Expression<Func<U>> alias)
{
return root.JoinQueryOver<U>(path, alias, joinType);
}
- public IQueryOver<U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias)
+ public IQueryOver<S,U> JoinQueryOver<U>(Expression<Func<IEnumerable<U>>> path, Expression<Func<U>> alias)
{
return root.JoinQueryOver<U>(path, alias, joinType);
}
}
- public class QueryOverJoinBuilderBase<R, T> where R : IQueryOver<T>
+ public class QueryOverJoinBuilderBase<R, S, T> where R : IQueryOver<S,T>
{
protected R root;
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverLockBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverLockBuilder.cs 2009-11-28 14:04:43 UTC (rev 4867)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverLockBuilder.cs 2009-11-28 21:09:24 UTC (rev 4868)
@@ -9,23 +9,23 @@
namespace NHibernate.Criterion.Lambda
{
- public class QueryOverLockBuilder<T> : QueryOverLockBuilderBase<QueryOver<T>, T>
+ public class QueryOverLockBuilder<S,T> : QueryOverLockBuilderBase<QueryOver<S,T>, S, T>
{
- public QueryOverLockBuilder(QueryOver<T> root, Expression<Func<object>> alias)
+ public QueryOverLockBuilder(QueryOver<S,T> root, Expression<Func<object>> alias)
: base(root, alias) { }
}
- public class IQueryOverLockBuilder<T> : QueryOverLockBuilderBase<IQueryOver<T>, T>
+ public class IQueryOverLockBuilder<S,T> : QueryOverLockBuilderBase<IQueryOver<S,T>, S, T>
{
- public IQueryOverLockBuilder(IQueryOver<T> root, Expression<Func<object>> alias)
+ public IQueryOverLockBuilder(IQueryOver<S,T> root, Expression<Func<object>> alias)
: base(root, alias) { }
}
- public class QueryOverLockBuilderBase<R, T> where R : IQueryOver<T>
+ public class QueryOverLockBuilderBase<R, S, T> where R : IQueryOver<S,T>
{
protected R root;
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs 2009-11-28 14:04:43 UTC (rev 4867)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverOrderBuilder.cs 2009-11-28 21:09:24 UTC (rev 4868)
@@ -9,29 +9,29 @@
namespace NHibernate.Criterion.Lambda
{
- public class QueryOverOrderBuilder<T> : QueryOverOrderBuilderBase<QueryOver<T>, T>
+ public class QueryOverOrderBuilder<S,T> : QueryOverOrderBuilderBase<QueryOver<S,T>, S, T>
{
- public QueryOverOrderBuilder(QueryOver<T> root, Expression<Func<T, object>> path) : base(root, path)
+ public QueryOverOrderBuilder(QueryOver<S,T> root, Expression<Func<T, object>> path) : base(root, path)
{}
- public QueryOverOrderBuilder(QueryOver<T> root, Expression<Func<object>> path) : base(root, path)
+ public QueryOverOrderBuilder(QueryOver<S,T> root, Expression<Func<object>> path) : base(root, path)
{}
}
- public class IQueryOverOrderBuilder<T> : QueryOverOrderBuilderBase<IQueryOver<T>, T>
+ public class IQueryOverOrderBuilder<S,T> : QueryOverOrderBuilderBase<IQueryOver<S,T>, S, T>
{
- public IQueryOverOrderBuilder(IQueryOver<T> root, Expression<Func<T, object>> path) : base(root, path)
+ public IQueryOverOrderBuilder(IQueryOver<S,T> root, Expression<Func<T, object>> path) : base(root, path)
{}
- public IQueryOverOrderBuilder(IQueryOver<T> root, Expression<Func<object>> path) : base(root, path)
+ public IQueryOverOrderBuilder(IQueryOver<S,T> root, Expression<Func<object>> path) : base(root, path)
{}
}
- public class QueryOverOrderBuilderBase<R, T> where R : IQueryOver<T>
+ public class QueryOverOrderBuilderBase<R, S, T> where R : IQueryOver<S, T>
{
protected R root;
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs 2009-11-28 14:04:43 UTC (rev 4867)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs 2009-11-28 21:09:24 UTC (rev 4868)
@@ -9,15 +9,15 @@
namespace NHibernate.Criterion.Lambda
{
- public class QueryOverProjectionBuilder<R, T>
+ public class QueryOverProjectionBuilder<R, S, T>
{
private R fluentReturn;
- private IQueryOver<T> criteria;
+ private IQueryOver<S,T> criteria;
private ProjectionList projectionList;
private IProjection lastProjection = null;
- public QueryOverProjectionBuilder(R fluentReturn, IQueryOver<T> criteria)
+ public QueryOverProjectionBuilder(R fluentReturn, IQueryOver<S,T> criteria)
{
this.fluentReturn = fluentReturn;
this.criteria = criteria;
@@ -52,7 +52,7 @@
/// <summary>
/// Create an alias for the previous projection
/// </summary>
- public QueryOverProjectionBuilder<R, T> WithAlias(Expression<Func<object>> alias)
+ public QueryOverProjectionBuilder<R, S, T> WithAlias(Expression<Func<object>> alias)
{
string aliasContainer = ExpressionProcessor.FindMemberExpression(alias.Body);
lastProjection = Projections.Alias(lastProjection, aliasContainer);
@@ -62,7 +62,7 @@
/// <summary>
/// Select an arbitrary projection
/// </summary>
- public QueryOverProjectionBuilder<R, T> Select(IProjection projection)
+ public QueryOverProjectionBuilder<R, S, T> Select(IProjection projection)
{
PushProjection(projection);
return this;
@@ -71,7 +71,7 @@
/// <summary>
/// A property average value
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectAvg(Expression<Func<T, object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectAvg(Expression<Func<T, object>> expression)
{
PushProjection(Projections.Avg(expression));
return this;
@@ -80,7 +80,7 @@
/// <summary>
/// A property average value
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectAvg(Expression<Func<object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectAvg(Expression<Func<object>> expression)
{
PushProjection(Projections.Avg(expression));
return this;
@@ -89,7 +89,7 @@
/// <summary>
/// A property value count
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectCount(Expression<Func<T, object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectCount(Expression<Func<T, object>> expression)
{
PushProjection(Projections.Count(expression));
return this;
@@ -98,7 +98,7 @@
/// <summary>
/// A property value count
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectCount(Expression<Func<object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectCount(Expression<Func<object>> expression)
{
PushProjection(Projections.Count(expression));
return this;
@@ -107,7 +107,7 @@
/// <summary>
/// A distinct property value count
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectCountDistinct(Expression<Func<T, object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectCountDistinct(Expression<Func<T, object>> expression)
{
PushProjection(Projections.CountDistinct(expression));
return this;
@@ -116,7 +116,7 @@
/// <summary>
/// A distinct property value count
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectCountDistinct(Expression<Func<object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectCountDistinct(Expression<Func<object>> expression)
{
PushProjection(Projections.CountDistinct(expression));
return this;
@@ -125,7 +125,7 @@
/// <summary>
/// A grouping property value
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectGroup(Expression<Func<T, object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectGroup(Expression<Func<T, object>> expression)
{
PushProjection(Projections.Group(expression));
return this;
@@ -134,7 +134,7 @@
/// <summary>
/// A grouping property value
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectGroup(Expression<Func<object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectGroup(Expression<Func<object>> expression)
{
PushProjection(Projections.Group(expression));
return this;
@@ -143,7 +143,7 @@
/// <summary>
/// A property maximum value
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectMax(Expression<Func<T, object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectMax(Expression<Func<T, object>> expression)
{
PushProjection(Projections.Max(expression));
return this;
@@ -152,7 +152,7 @@
/// <summary>
/// A property maximum value
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectMax(Expression<Func<object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectMax(Expression<Func<object>> expression)
{
PushProjection(Projections.Max(expression));
return this;
@@ -161,7 +161,7 @@
/// <summary>
/// A property minimum value
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectMin(Expression<Func<T, object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectMin(Expression<Func<T, object>> expression)
{
PushProjection(Projections.Min(expression));
return this;
@@ -170,7 +170,7 @@
/// <summary>
/// A property minimum value
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectMin(Expression<Func<object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectMin(Expression<Func<object>> expression)
{
PushProjection(Projections.Min(expression));
return this;
@@ -179,7 +179,7 @@
/// <summary>
/// A projected property value
/// </summary>
- public QueryOverProjectionBuilder<R, T> Select(Expression<Func<T, object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> Select(Expression<Func<T, object>> expression)
{
PushProjection(Projections.Property(expression));
return this;
@@ -188,13 +188,13 @@
/// <summary>
/// A projected property value
/// </summary>
- public QueryOverProjectionBuilder<R, T> Select(Expression<Func<object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> Select(Expression<Func<object>> expression)
{
PushProjection(Projections.Property(expression));
return this;
}
- public QueryOverProjectionBuilder<R, T> SelectSubQuery<U>(QueryOver<U> detachedQueryOver)
+ public QueryOverProjectionBuilder<R, S, T> SelectSubQuery<U>(QueryOver<U> detachedQueryOver)
{
PushProjection(Projections.SubQuery(detachedQueryOver));
return this;
@@ -203,7 +203,7 @@
/// <summary>
/// A property value sum
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectSum(Expression<Func<T, object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectSum(Expression<Func<T, object>> expression)
{
PushProjection(Projections.Sum(expression));
return this;
@@ -212,7 +212,7 @@
/// <summary>
/// A property value sum
/// </summary>
- public QueryOverProjectionBuilder<R, T> SelectSum(Expression<Func<object>> expression)
+ public QueryOverProjectionBuilder<R, S, T> SelectSum(Expression<Func<object>> expression)
{
PushProjection(Projections.Sum(expression));
return this;
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs 2009-11-28 14:04:43 UTC (rev 4867)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs 2009-11-28 21:09:24 UTC (rev 4868)
@@ -10,24 +10,24 @@
namespace NHibernate.Criterion.Lambda
{
- public class QueryOverRestrictionBuilder<T> : QueryOverRestrictionBuilderBase<QueryOver<T>, T>
+ public class QueryOverRestrictionBuilder<S,T> : QueryOverRestrictionBuilderBase<QueryOver<S,T>, S, T>
{
- public QueryOverRestrictionBuilder(QueryOver<T> root, string propertyName)
+ public QueryOverRestrictionBuilder(QueryOver<S,T> root, string propertyName)
: base(root, propertyName) { }
}
- public class IQueryOverRestrictionBuilder<T> : QueryOverRestrictionBuilderBase<IQueryOver<T>, T>
+ public class IQueryOverRestrictionBuilder<S,T> : QueryOverRestrictionBuilderBase<IQueryOver<S,T>, S, T>
{
- public IQueryOverRestrictionBuilder(IQueryOver<T> root, string propertyName)
+ public IQueryOverRestrictionBuilder(IQueryOver<S,T> root, string propertyName)
: base(root, propertyName) { }
}
- public class QueryOverRestrictionBuilderBase<R, T>
- where R : IQueryOver<T>
+ public class QueryOverRestrictionBuilderBase<R,S,T>
+ where R : IQueryOver<S,T>
{
public class LambdaBetweenBuilder
{
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs 2009-11-28 14:04:43 UTC (rev 4867)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryBuilder.cs 2009-11-28 21:09:24 UTC (rev 4868)
@@ -9,25 +9,25 @@
namespace NHibernate.Criterion.Lambda
{
- public class QueryOverSubqueryBuilder<T> : QueryOverSubqueryBuilderBase<QueryOver<T>, T, QueryOverSubqueryPropertyBuilder<T>>
+ public class QueryOverSubqueryBuilder<S,T> : QueryOverSubqueryBuilderBase<QueryOver<S,T>, S, T, QueryOverSubqueryPropertyBuilder<S,T>>
{
- public QueryOverSubqueryBuilder(QueryOver<T> root)
+ public QueryOverSubqueryBuilder(QueryOver<S,T> root)
: base(root) { }
}
- public class IQueryOverSubqueryBuilder<T> : QueryOverSubqueryBuilderBase<IQueryOver<T>, T, IQueryOverSubqueryPropertyBuilder<T>>
+ public class IQueryOverSubqueryBuilder<S,T> : QueryOverSubqueryBuilderBase<IQueryOver<S,T>, S, T, IQueryOverSubqueryPropertyBuilder<S,T>>
{
- public IQueryOverSubqueryBuilder(IQueryOver<T> root)
+ public IQueryOverSubqueryBuilder(IQueryOver<S,T> root)
: base(root) { }
}
- public class QueryOverSubqueryBuilderBase<R, T, S>
- where R : IQueryOver<T>
- where S : QueryOverSubqueryPropertyBuilderBase, new()
+ public class QueryOverSubqueryBuilderBase<R, S, T, B>
+ where R : IQueryOver<S,T>
+ where B : QueryOverSubqueryPropertyBuilderBase, new()
{
protected R root;
@@ -121,21 +121,21 @@
return root;
}
- public S WhereProperty(Expression<Func<T, object>> expression)
+ public B WhereProperty(Expression<Func<T, object>> expression)
{
string property = ExpressionProcessor.FindMemberExpression(expression.Body);
- return (S)new S().Set(root, property, null);
+ return (B)new B().Set(root, property, null);
}
- public S WhereProperty(Expression<Func<object>> expression)
+ public B WhereProperty(Expression<Func<object>> expression)
{
string property = ExpressionProcessor.FindMemberExpression(expression.Body);
- return (S)new S().Set(root, property, null);
+ return (B)new B().Set(root, property, null);
}
- public S WhereValue(object value)
+ public B WhereValue(object value)
{
- return (S)new S().Set(root, null, value);
+ return (B)new B().Set(root, null, value);
}
}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs 2009-11-28 14:04:43 UTC (rev 4867)
+++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverSubqueryPropertyBuilder.cs 2009-11-28 21:09:24 UTC (rev 4868)
@@ -9,7 +9,7 @@
namespace NHibernate.Criterion.Lambda
{
- public class QueryOverSubqueryPropertyBuilder<T> : QueryOverSubqueryPropertyBuilderBase<QueryOver<T>, T>
+ public class QueryOverSubqueryPropertyBuilder<S,T> : QueryOverSubqueryPropertyBuilderBase<QueryOver<S,T>, S, T>
{
public QueryOverSubqueryPropertyBuilder()
@@ -17,7 +17,7 @@
}
- public class IQueryOverSubqueryPropertyBuilder<T> : QueryOverSubqueryPropertyBuilderBase<IQueryOver<T>, T>
+ public class IQueryOverSubqueryPropertyBuilder<S,T> : QueryOverSubqueryPropertyBuilderBase<IQueryOver<S,T>, S, T>
{
public IQueryOverSubqueryPropertyBuilder()
@@ -32,8 +32,8 @@
internal abstract QueryOverSubqueryPropertyBuilderBase Set(object root, string path, object value);
}
- public class QueryOverSubqueryPropertyBuilderBase<R, T> : QueryOverSubqueryPropertyBuilderBase
- where R : IQueryOver<T>
+ public class QueryOverSubqueryPropertyBuilderBase<R, S, T> : QueryOverSubqueryPropertyBuilderBase
+ where R : IQueryOver<S,T>
{
protected R root;
Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-28 14:04:43 UTC (rev 4867)
+++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2009-11-28 21:09:24 UTC (rev 4868)
@@ -19,14 +19,14 @@
protected QueryOver() { }
- public static QueryOver<T> Of<T>()
+ public static QueryOver<T,T> Of<T>()
{
- return new QueryOver<T>();
+ return new QueryOver<T,T>();
}
- public static QueryOver<T> Of<T>(Expression<Func<T>> alias)
+ public static QueryOver<T,T> Of<T>(Expression<Func<T>> alias)
{
- return new QueryOver<T>(alias);
+ return new QueryOver<T,T>(alias);
}
public ICriteria UnderlyingCriteria
@@ -41,11 +41,105 @@
}
+ [Serializable]
+ public class QueryOver<T> : QueryOver, IQueryOver<T>
+ {
+
+ private IList<T> List()
+ {
+ return _criteria.List<T>();
+ }
+
+ private IList<U> List<U>()
+ {
+ return _criteria.List<U>();
+ }
+
+ private T UniqueResult()
+ {
+ return _criteria.UniqueResult<T>();
+ }
+
+ private U UniqueResult<U>()
+ {
+ return _criteria.UniqueResult<U>();
+ }
+
+ private IEnumerable<T> Future()
+ {
+ return _criteria.Future<T>();
+ }
+
+ private IEnumerable<U> Future<U>()
+ {
+ return _criteria.Future<U>();
+ }
+
+ private IFutureValue<T> FutureValue()
+ {
+ return _criteria.FutureValue<T>();
+ }
+
+ private IFutureValue<U> FutureValue<U>()
+ {
+ return _criteria.FutureValue<U>();
+ }
+
+ /// <summary>
+ /// Get an executable instance of <c>IQueryOver<T></c>,
+ /// to actually run the query.</summary>
+ public IQueryOver<T> GetExecutableQueryOver(ISession session)
+ {
+ _impl.Session = session.GetSessionImplementation();
+ return this;
+ }
+
+ /// <summary>
+ /// Method to allow comparison of detached query in Lambda expression
+ /// e.g., p => p.Name == myQuery.As<string>
+ /// </summary>
+ /// <typeparam name="S">type returned by query</typeparam>
+ /// <returns>throws an exception if evaluated directly at runtime.</returns>
+ public S As<S>()
+ {
+ throw new HibernateException("Incorrect syntax; .As<T> method is for use in Lambda expressions only.");
+ }
+
+
+ ICriteria IQueryOver<T>.UnderlyingCriteria
+ { get { return UnderlyingCriteria; } }
+
+ IList<T> IQueryOver<T>.List()
+ { return List(); }
+
+ IList<U> IQueryOver<T>.List<U>()
+ { return List<U>(); }
+
+ T IQueryOver<T>.UniqueResult()
+ { return UniqueResult(); }
+
+ U IQueryOver<T>.UniqueResult<U>()
+ { return UniqueResult<U>(); }
+
+ IEnumerable<T> IQueryOver<T>.Future()
+ { return Future(); }
+
+ IEnumerable<U> IQueryOver<T>.Future<U>()
+ { return Future<U>(); }
+
+ IFutureValue<T> IQueryOver<T>.FutureValue()
+ { return FutureValue(); }
+
+ IFutureValue<U> IQueryOver<T>.FutureValue<U>()
+ { return FutureValue<U>(); }
+
+ }
+
/// <summary>
/// Implementation of the <see cref="IQueryOver<T>"/> interface
/// </summary>
[Serializable]
- public class QueryOver<T> : QueryOver, IQueryOver<T>
+ public class QueryOver<R,T> : QueryOver<R>, IQueryOver<R,T>
{
protected internal QueryOver()
@@ -73,88 +167,77 @@
_criteria = criteria;
}
- /// <summary>
- /// Method to allow comparison of detached query in Lambda expression
- /// e.g., p => p.Name == myQuery.As<string>
- /// </summary>
- /// <typeparam name="R">type returned by query</typeparam>
- /// <returns>throws an exception if evaluated directly at runtime.</returns>
- public R As<R>()
+ public QueryOver<R,T> And(Expression<Func<T, bool>> expression)
{
- throw new HibernateException("Incorrect syntax; .As<T> method is for use in Lambda expressions only.");
- }
-
- public QueryOver<T> And(Expression<Func<T, bool>> expression)
- {
return Add(expression);
}
- public QueryOver<T> And(Expression<Func<bool>> expression)
+ public QueryOver<R,T> And(Expression<Func<bool>> expression)
{
return Add(expression);
}
- public QueryOver<T> And(ICriterion expression)
+ public QueryOver<R,T> And(ICriterion expression)
{
return Add(expression);
}
- public QueryOver<T> AndNot(Expression<Func<T, bool>> expression)
+ public QueryOver<R,T> AndNot(Expression<Func<T, bool>> expression)
{
return AddNot(expression);
}
- public QueryOver<T> AndNot(Expression<Func<bool>> expression)
+ public QueryOver<R,T> AndNot(Expression<Func<bool>> expression)
{
return AddNot(expression);
}
- public QueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<T, object>> expression)
+ public QueryOverRestrictionBuilder<R,T> AndRestrictionOn(Expression<Func<T, object>> expression)
{
- return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ return new QueryOverRestrictionBuilder<R,T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
}
- public QueryOverRestrictionBuilder<T> AndRestrictionOn(Expression<Func<object>> expression)
+ public QueryOverRestrictionBuilder<R,T> AndRestrictionOn(Expression<Func<object>> expression)
{
- return new QueryOverRestrictionBuilder<T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
+ return new QueryOverRestrictionBuilder<R,T>(this, ExpressionProcessor.FindMemberExpression(expression.Body));
}
- public QueryOver<T> Where(Expression<Func<T, bool>> expression)
+ public QueryOver<R,T> Where(Expression<Func<T, bool>> expression)
{
return Add(expression);
}
- public QueryOver<T> Where(Expression<Func<bool>>...
[truncated message content] |