Skip to content

Commit

Permalink
Query: Add support for instance based SqlFunction
Browse files Browse the repository at this point in the history
Part of #10109
  • Loading branch information
smitpatel committed Nov 22, 2017
1 parent 9a7d3d1 commit f3a926b
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 76 deletions.
4 changes: 2 additions & 2 deletions src/EFCore.Relational/Metadata/Internal/DbFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ private static string BuildAnnotationName(string annotationPrefix, MethodBase me
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public virtual string DefaultSchema { get; [param: CanBeNull] set;}
public virtual string DefaultSchema { get; [param: CanBeNull] set; }

/// <summary>
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
Expand Down
48 changes: 42 additions & 6 deletions src/EFCore.Relational/Query/Expressions/SqlFunctionExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.EntityFrameworkCore.Query.Expressions
/// <summary>
/// Represents a SQL function call expression.
/// </summary>
[DebuggerDisplay("{this.FunctionName}({string.Join(\", \", this.Arguments)})")]
[DebuggerDisplay("{this.Instance}.{this.FunctionName}({string.Join(\", \", this.Arguments)})")]
public class SqlFunctionExpression : Expression
{
private readonly ReadOnlyCollection<Expression> _arguments;
Expand All @@ -34,7 +34,7 @@ public SqlFunctionExpression(
}

/// <summary>
/// Initializes a new instance of the Microsoft.EntityFrameworkCore.Query.Expressions.SqlFunctionExpression class.
/// Initializes a new instance of the <see cref="SqlFunctionExpression" /> class.
/// </summary>
/// <param name="functionName"> Name of the function. </param>
/// <param name="returnType"> The return type. </param>
Expand All @@ -51,16 +51,42 @@ public SqlFunctionExpression(
/// Initializes a new instance of the <see cref="SqlFunctionExpression" /> class.
/// </summary>
/// <param name="functionName"> Name of the function. </param>
/// <param name="returnType"> The return type. </param>
/// ///
/// <param name="schema"> The schema this function exists in if any. </param>
/// <param name="returnType"> The return type. </param>
/// <param name="arguments"> The arguments. </param>
public SqlFunctionExpression(
[NotNull] string functionName,
[NotNull] Type returnType,
[CanBeNull] string schema,
[NotNull] IEnumerable<Expression> arguments)
: this(/*instance*/ null, functionName, schema, returnType, arguments)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="SqlFunctionExpression" /> class.
/// </summary>
/// <param name="instance"> The instance on which the function is called. </param>
/// <param name="functionName"> Name of the function. </param>
/// <param name="returnType"> The return type. </param>
/// <param name="arguments"> The arguments. </param>
public SqlFunctionExpression(
[NotNull] Expression instance,
[NotNull] string functionName,
[NotNull] Type returnType,
[NotNull] IEnumerable<Expression> arguments)
: this(instance, functionName, /*schema*/ null, returnType, arguments)
{
}

private SqlFunctionExpression(
[CanBeNull] Expression instance,
[NotNull] string functionName,
[CanBeNull] string schema,
[NotNull] Type returnType,
[NotNull] IEnumerable<Expression> arguments)
{
Instance = instance;
FunctionName = functionName;
Type = returnType;
Schema = schema;
Expand All @@ -83,6 +109,11 @@ public SqlFunctionExpression(
/// </value>
public virtual string Schema { get; }

/// <summary>
/// The instance.
/// </summary>
public virtual Expression Instance { get; }

/// <summary>
/// The arguments.
/// </summary>
Expand Down Expand Up @@ -129,10 +160,11 @@ protected override Expression Accept(ExpressionVisitor visitor)
/// </remarks>
protected override Expression VisitChildren(ExpressionVisitor visitor)
{
var newInstance = Instance != null ? visitor.Visit(Instance) : null;
var newArguments = visitor.VisitAndConvert(_arguments, "VisitChildren");

return newArguments != _arguments
? new SqlFunctionExpression(FunctionName, Type, newArguments)
return newInstance != Instance || newArguments != _arguments
? new SqlFunctionExpression(newInstance, FunctionName, Schema, Type, newArguments)
: this;
}

Expand Down Expand Up @@ -161,6 +193,8 @@ public override bool Equals(object obj)
private bool Equals(SqlFunctionExpression other)
=> Type == other.Type
&& string.Equals(FunctionName, other.FunctionName)
&& string.Equals(Schema, other.Schema)
&& Instance.Equals(other.Instance)
&& _arguments.SequenceEqual(other._arguments);

/// <summary>
Expand All @@ -174,7 +208,9 @@ public override int GetHashCode()
unchecked
{
var hashCode = _arguments.Aggregate(0, (current, argument) => current + ((current * 397) ^ argument.GetHashCode()));
hashCode = (hashCode * 397) ^ (Instance?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ FunctionName.GetHashCode();
hashCode = (hashCode * 397) ^ (Schema?.GetHashCode() ?? 0);
hashCode = (hashCode * 397) ^ Type.GetHashCode();
return hashCode;
}
Expand Down
Loading

0 comments on commit f3a926b

Please sign in to comment.