Skip to content

Commit

Permalink
Add more MethodCallTranslators for SqlServer
Browse files Browse the repository at this point in the history
Support projecting DTOs
  • Loading branch information
smitpatel committed Feb 23, 2019
1 parent 65dbb6e commit b416870
Show file tree
Hide file tree
Showing 52 changed files with 724 additions and 1,353 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ private readonly List<IExpressionFragmentTranslator> _translators
= new List<IExpressionFragmentTranslator>
{
new ComparisonTranslator(),
new StringConcatTranslator()
};

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ protected RelationalCompositeMethodCallTranslator(
= new List<IMethodCallTranslator>
{
new EnumHasFlagTranslator(),
new EqualsTranslator(),
new GetValueOrDefaultTranslator(),
new IsNullOrEmptyTranslator(),
new LikeTranslator()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ protected override Expression VisitExtension(Expression extensionExpression)
sqlBinary.OperatorType == ExpressionType.NotEqual,
sqlBinary.TypeMapping);
}

}

return base.VisitExtension(extensionExpression);
Expand Down
36 changes: 35 additions & 1 deletion src/EFCore.Relational/Query/PipeLine/QuerySqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,48 @@ protected override Expression VisitSqlBinary(SqlBinaryExpression sqlBinaryExpres
}
else
{
var needsParenthesis = RequiresBrackets(sqlBinaryExpression.Left);

if (needsParenthesis)
{
_relationalCommandBuilder.Append("(");
}

Visit(sqlBinaryExpression.Left);

if (needsParenthesis)
{
_relationalCommandBuilder.Append(")");
}

_relationalCommandBuilder.Append(_operatorMap[sqlBinaryExpression.OperatorType]);

needsParenthesis = RequiresBrackets(sqlBinaryExpression.Right);

if (needsParenthesis)
{
_relationalCommandBuilder.Append("(");
}

Visit(sqlBinaryExpression.Right);

if (needsParenthesis)
{
_relationalCommandBuilder.Append(")");
}


}

return sqlBinaryExpression;
}

private bool RequiresBrackets(SqlExpression expression)
{
return expression is SqlBinaryExpression sqlBinary
&& sqlBinary.OperatorType != ExpressionType.Coalesce;
}

protected override Expression VisitSqlConstant(SqlConstantExpression sqlConstantExpression)
{
_relationalCommandBuilder
Expand Down Expand Up @@ -349,7 +383,7 @@ protected override Expression VisitExists(ExistsExpression existsExpression)
{
if (existsExpression.Negated)
{
_relationalCommandBuilder.AppendLine("NOT EXISTS (");
_relationalCommandBuilder.Append("NOT ");
}

_relationalCommandBuilder.AppendLine("EXISTS (");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public override Expression Visit(Expression expression)
}

if (!(expression is NewExpression
|| expression is MemberInitExpression
|| expression is EntityShaperExpression))
{

Expand Down Expand Up @@ -86,7 +87,7 @@ protected override Expression VisitExtension(Expression node)
protected override Expression VisitNew(NewExpression newExpression)
{
var newArguments = new Expression[newExpression.Arguments.Count];
for (var i = 0; i < newExpression.Arguments.Count; i++)
for (var i = 0; i < newArguments.Length; i++)
{
// TODO: Members can be null????
var projectionMember = _projectionMembers.Peek().AddMember(newExpression.Members[i]);
Expand All @@ -97,5 +98,23 @@ protected override Expression VisitNew(NewExpression newExpression)

return newExpression.Update(newArguments);
}

protected override Expression VisitMemberInit(MemberInitExpression memberInitExpression)
{
var newExpression = (NewExpression)Visit(memberInitExpression.NewExpression);
var newBindings = new MemberAssignment[memberInitExpression.Bindings.Count];
for (var i = 0; i < newBindings.Length; i++)
{
// TODO: Members can be null????
var memberAssignment = (MemberAssignment)memberInitExpression.Bindings[i];

var projectionMember = _projectionMembers.Peek().AddMember(memberAssignment.Member);
_projectionMembers.Push(projectionMember);

newBindings[i] = memberAssignment.Update(Visit(memberAssignment.Expression));
}

return memberInitExpression.Update(newExpression, newBindings);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Microsoft.EntityFrameworkCore.Relational.Query.PipeLine
public class RelationalQueryableMethodTranslatingExpressionVisitor : QueryableMethodTranslatingExpressionVisitor
{
private readonly RelationalSqlTranslatingExpressionVisitor _sqlTranslator;
private readonly RelationalProjectionBindingExpressionVisitor _projectionBindingExpressionVisitor;
private readonly IRelationalTypeMappingSource _typeMappingSource;

public RelationalQueryableMethodTranslatingExpressionVisitor(
Expand All @@ -28,20 +29,47 @@ public RelationalQueryableMethodTranslatingExpressionVisitor(
typeMappingApplyingExpressionVisitor,
memberTranslatorProvider,
methodCallTranslatorProvider);

_projectionBindingExpressionVisitor = new RelationalProjectionBindingExpressionVisitor(_sqlTranslator);
_typeMappingSource = typeMappingSource;
}

protected override ShapedQueryExpression TranslateAll(ShapedQueryExpression source, LambdaExpression predicate)
{
//var translation = TranslateLambdaExpression(source, predicate, true);
var translation = TranslateLambdaExpression(source, predicate, true);

if (translation != null)
{
var selectExpression = (SelectExpression)source.QueryExpression;

selectExpression.ApplyPredicate(
new SqlNotExpression(translation, _typeMappingSource.FindMapping(typeof(bool))));

//if (translation?.IsCondition == true)
//{
// ((SelectExpression)source.QueryExpression).ApplyPredicate(
// new SqlNotExpression(translation, typeof(bool), _typeMappingSource.FindMapping(typeof(bool)), true));

// return source;
//}
selectExpression.ApplyProjection(new Dictionary<ProjectionMember, Expression>());

translation = new ExistsExpression(
selectExpression,
true,
_typeMappingSource.FindMapping(typeof(bool)))
.ConvertToValue(true);

var projectionMapping = new Dictionary<ProjectionMember, Expression>
{
{ new ProjectionMember(), translation }
};

source.QueryExpression = new SelectExpression(
projectionMapping,
new List<TableExpressionBase>());

source.ShaperExpression
= Expression.Lambda(
new ProjectionBindingExpression(source.QueryExpression, new ProjectionMember(), typeof(bool)),
source.ShaperExpression.Parameters);

return source;
}

throw new InvalidOperationException();
}
Expand Down Expand Up @@ -132,7 +160,15 @@ protected override ShapedQueryExpression TranslateAverage(ShapedQueryExpression
return AggregateResultShaper(source, projection, throwOnNullResult: true, resultType);
}

protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression source, Type resultType) => throw new NotImplementedException();
protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression source, Type resultType)
{
if (source.ShaperExpression.ReturnType == resultType)
{
return source;
}

throw new NotImplementedException();
}

protected override ShapedQueryExpression TranslateConcat(ShapedQueryExpression source1, ShapedQueryExpression source2) => throw new NotImplementedException();

Expand Down Expand Up @@ -316,7 +352,7 @@ protected override ShapedQueryExpression TranslateSelect(ShapedQueryExpression s

var newSelectorBody = new ReplacingExpressionVisitor(parameterBindings).Visit(selector.Body);

newSelectorBody = new RelationalProjectionBindingExpressionVisitor(_sqlTranslator)
newSelectorBody = _projectionBindingExpressionVisitor
.Translate((SelectExpression)source.QueryExpression, newSelectorBody);

source.ShaperExpression = Expression.Lambda(newSelectorBody, source.ShaperExpression.Parameters);
Expand Down Expand Up @@ -483,6 +519,8 @@ private ShapedQueryExpression AggregateResultShaper(
{ new ProjectionMember(), projection }
});

selectExpression.ClearOrdering();

Expression shaper = new ProjectionBindingExpression(selectExpression, new ProjectionMember(), projection.Type);

if (throwOnNullResult)
Expand All @@ -500,10 +538,9 @@ private ShapedQueryExpression AggregateResultShaper(
.Single(ci => ci.GetParameters().Length == 1),
Expression.Constant(RelationalStrings.NoElements)),
projection.Type),
resultVariable),
resultType != resultVariable.Type
? Expression.Convert(resultVariable, resultType)
: (Expression)resultVariable);
resultType != resultVariable.Type
? Expression.Convert(resultVariable, resultType)
: (Expression)resultVariable));
}
else if (resultType.IsNullableType())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected override Expression VisitChildren(ExpressionVisitor visitor)
var elseResult = (SqlExpression)visitor.Visit(ElseResult);

return changed || elseResult != ElseResult
? new CaseExpression(whenClauses, elseResult, Type, TypeMapping)
? new CaseExpression(whenClauses, elseResult, Type, TypeMapping, ShouldBeValue)
: this;
}

Expand Down
Loading

0 comments on commit b416870

Please sign in to comment.