protected override Expression VisitMemberExpression(MemberExpression expression) { var isIdentifier = _isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name); if (!isIdentifier) { _memberExpressionDepth++; } var result = base.VisitMemberExpression(expression); if (!isIdentifier) { _memberExpressionDepth--; } if (_isEntityDecider.IsEntity(expression.Type) && _memberExpressionDepth > 0 && _joiner.CanAddJoin(expression)) { var key = ExpressionKeyVisitor.Visit(expression, null); return(_joiner.AddJoin(result, key)); } return(result); }
protected override Expression VisitMemberExpression(MemberExpression expression) { if (_isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name)) { _hasIdentifier = true; } else if (_hasIdentifier) { _identifierMemberExpressionDepth++; } var result = base.VisitMemberExpression(expression); if (_hasIdentifier) { _identifierMemberExpressionDepth--; } if (_isEntityDecider.IsEntity(expression.Type) && (!_hasIdentifier || _identifierMemberExpressionDepth > 0) && _joiner.CanAddJoin(expression)) { var key = ExpressionKeyVisitor.Visit(expression, null); return(_joiner.AddJoin(result, key)); } _hasIdentifier = false; return(result); }
protected override Expression VisitMember(MemberExpression expression) { var isIdentifier = _isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name); if (isIdentifier) { _hasIdentifier = true; } if (!isIdentifier) { _memberExpressionDepth++; } var result = base.VisitMember(expression); if (!isIdentifier) { _memberExpressionDepth--; } if (_isEntityDecider.IsEntity(expression.Type) && ((_requiresJoinForNonIdentifier && !_hasIdentifier) || _memberExpressionDepth > 0) && _joiner.CanAddJoin(expression)) { var key = ExpressionKeyVisitor.Visit(expression, null); return(_joiner.AddJoin(result, key)); } _hasIdentifier = false; return(result); }
// We would usually get NULL if one of our inner member expresions was null. // However, it's possible a method call will convert the null value from the failed join into a non-null value. // This could be optimized by actually checking what the method does. For example StartsWith("s") would leave null as null and would still allow us to inner join. //protected override Expression VisitMethodCallExpression(MethodCallExpression expression) //{ // Expression result = base.VisitMethodCallExpression(expression); // return result; //} protected override Expression VisitMemberExpression(MemberExpression expression) { // The member expression we're visiting might be on the end of a variety of things, such as: // a.B // a.B.C // (a.B ?? a.C).D // I'm not sure what processing re-linq does to strange member expressions. // TODO: I suspect this code doesn't add the right joins for the last case. _memberExpressionDepth++; var result = base.VisitMemberExpression(expression); _memberExpressionDepth--; ExpressionValues values = _values.Pop().Operation(pvs => pvs.MemberAccess(expression.Type)); if (_isEntityDecider.IsEntity(expression.Type)) { // Don't add joins for things like a.B == a.C where B and C are entities. // We only need to join B when there's something like a.B.D. // TODO: Add an exception for the Id property. if (_memberExpressionDepth > 0) { AddJoin(expression); } string key = ExpressionKeyVisitor.Visit(expression, null); values.MemberExpressionValuesIfEmptyOuterJoined[key] = PossibleValueSet.CreateNull(expression.Type); } SetResultValues(values); return(result); }
public static string Visit(Expression expression, IDictionary <ConstantExpression, NamedParameter> parameters) { var visitor = new ExpressionKeyVisitor(parameters); visitor.Visit(expression); return(visitor.ToString()); }
/// <summary> /// Generates the key for the expression. /// </summary> /// <param name="rootExpression">The expression.</param> /// <param name="sessionFactory">The session factory.</param> /// <param name="parameters">Parameters found in <paramref name="rootExpression"/>.</param> /// <returns>The key for the expression.</returns> public static string Visit( Expression rootExpression, IDictionary <ConstantExpression, NamedParameter> parameters, ISessionFactoryImplementor sessionFactory) { var visitor = new ExpressionKeyVisitor(parameters, sessionFactory); visitor.Visit(rootExpression); return(visitor.ToString()); }
// We would usually get NULL if one of our inner member expressions was null. // However, it's possible a method call will convert the null value from the failed join into a non-null value. // This could be optimized by actually checking what the method does. For example StartsWith("s") would leave null as null and would still allow us to inner join. //protected override Expression VisitMethodCall(MethodCallExpression expression) //{ // Expression result = base.VisitMethodCall(expression); // return result; //} protected override Expression VisitMember(MemberExpression expression) { // The member expression we're visiting might be on the end of a variety of things, such as: // a.B // a.B.C // (a.B ?? a.C).D // I'm not sure what processing re-linq does to strange member expressions. // TODO: I suspect this code doesn't add the right joins for the last case. // A static member expression such as DateTime.Now has a null Expression. if (expression.Expression == null) { // A static member call is never a join, and it is not an instance member access either: leave // the current value on stack, untouched. return(base.VisitMember(expression)); } var isIdentifier = _isEntityDecider.IsIdentifier( expression.Expression.Type, expression.Member.Name); if (!isIdentifier) { _memberExpressionDepth++; } var result = base.VisitMember(expression); if (!isIdentifier) { _memberExpressionDepth--; } ExpressionValues values = _values.Pop().Operation(pvs => pvs.MemberAccess(expression.Type)); if (_isEntityDecider.IsEntity(expression.Type)) { // Don't add joins for things like a.B == a.C where B and C are entities. // We only need to join B when there's something like a.B.D. var key = ExpressionKeyVisitor.Visit(expression, null); if (_memberExpressionDepth > 0 && _joiner.CanAddJoin(expression)) { result = _joiner.AddJoin(result, key); } values.MemberExpressionValuesIfEmptyOuterJoined[key] = PossibleValueSet.CreateNull(expression.Type); } SetResultValues(values); return(result); }
private Expression AddJoin(MemberExpression expression) { string key = ExpressionKeyVisitor.Visit(expression, null); LeftJoinClause join; if (!_joins.TryGetValue(key, out join)) { join = new LeftJoinClause(_nameGenerator.GetNewName(), expression.Type, expression); _joins.Add(key, join); } return(new QuerySourceReferenceExpression(join)); }
protected internal Expression AddJoin(MemberExpression expression) { string key = ExpressionKeyVisitor.Visit(expression, null); NhJoinClause join; if (!_joins.TryGetValue(key, out join)) { join = new NhJoinClause(_nameGenerator.GetNewName(), expression.Type, expression); _joins.Add(key, join); } QuerySourceReferenceExpression newExpr = new QuerySourceReferenceExpression(join); if (!_expressionMap.ContainsKey(expression)) { _expressionMap.Add(expression, newExpr); } return(newExpr); }
protected override Expression VisitMember(MemberExpression expression) { // A static member expression such as DateTime.Now has a null Expression. if (expression.Expression == null) { // A static member call is never a join, and it is not an instance member access either. return(base.VisitMember(expression)); } var isIdentifier = _isEntityDecider.IsIdentifier(expression.Expression.Type, expression.Member.Name); if (isIdentifier) { _hasIdentifier = true; } if (!isIdentifier) { _memberExpressionDepth++; } var result = base.VisitMember(expression); if (!isIdentifier) { _memberExpressionDepth--; } if (_isEntityDecider.IsEntity(expression.Type) && ((_requiresJoinForNonIdentifier && !_hasIdentifier) || _memberExpressionDepth > 0) && _joiner.CanAddJoin(expression)) { var key = ExpressionKeyVisitor.Visit(expression, null); return(_joiner.AddJoin(result, key)); } _hasIdentifier = false; return(result); }
protected override Expression VisitMemberExpression(MemberExpression expression) { ArgumentUtility.CheckNotNull("expression", expression); Expression newExpression; try { _memberExpressionDepth++; newExpression = base.VisitExpression(expression.Expression); } finally { _memberExpressionDepth--; } bool isEntity = _isEntityDecider.IsEntity(expression.Type); if (isEntity) { // See (h) why we do not check for _memberExpressionDepth here! AddPossibility(ExpressionKeyVisitor.Visit(expression, null), N); } if (_memberExpressionDepth > 0 && isEntity) { return(AddJoin(expression)); } else { if (newExpression != expression.Expression) { return(Expression.MakeMemberAccess(newExpression, expression.Member)); } return(expression); } }