diff --git a/src/EFCore.Cosmos/Query/Internal/SqlUnaryExpression.cs b/src/EFCore.Cosmos/Query/Internal/SqlUnaryExpression.cs index 8df774abcec..ba625a74559 100644 --- a/src/EFCore.Cosmos/Query/Internal/SqlUnaryExpression.cs +++ b/src/EFCore.Cosmos/Query/Internal/SqlUnaryExpression.cs @@ -92,7 +92,7 @@ public override void Print(ExpressionPrinter expressionPrinter) { Check.NotNull(expressionPrinter, nameof(expressionPrinter)); - expressionPrinter.Append(OperatorType); + expressionPrinter.Append(OperatorType.ToString()); expressionPrinter.Append("("); expressionPrinter.Visit(Operand); expressionPrinter.Append(")"); diff --git a/src/EFCore.Design/Design/Internal/CSharpHelper.cs b/src/EFCore.Design/Design/Internal/CSharpHelper.cs index 781909d2c3a..a4f7b39bdcd 100644 --- a/src/EFCore.Design/Design/Internal/CSharpHelper.cs +++ b/src/EFCore.Design/Design/Internal/CSharpHelper.cs @@ -580,7 +580,7 @@ private string Array(Type type, IEnumerable values, bool vertical = false) if (valuesList.Count == 0) { builder - .Append(' ') + .Append(" ") .Append(Reference(type)) .Append("[0]"); } diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs index 54e41c108c4..1f2a1f89a46 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpEntityTypeGenerator.cs @@ -142,7 +142,7 @@ private void GenerateKeylessAttribute(IEntityType entityType) { if (entityType.FindPrimaryKey() == null) { - _sb.AppendLine(new AttributeWriter(nameof(KeylessAttribute))); + _sb.AppendLine(new AttributeWriter(nameof(KeylessAttribute)).ToString()); } } @@ -166,7 +166,7 @@ private void GenerateTableAttribute(IEntityType entityType) tableAttribute.AddParameter($"{nameof(TableAttribute.Schema)} = {_code.Literal(schema)}"); } - _sb.AppendLine(tableAttribute); + _sb.AppendLine(tableAttribute.ToString()); } } @@ -245,7 +245,7 @@ private void GenerateKeyAttribute(IProperty property) var key = property.FindContainingPrimaryKey(); if (key != null) { - _sb.AppendLine(new AttributeWriter(nameof(KeyAttribute))); + _sb.AppendLine(new AttributeWriter(nameof(KeyAttribute)).ToString()); } } @@ -271,7 +271,7 @@ private void GenerateColumnAttribute(IProperty property) columnAttribute.AddParameter($"{nameof(ColumnAttribute.TypeName)} = {delimitedColumnType}"); } - _sb.AppendLine(columnAttribute); + _sb.AppendLine(columnAttribute.ToString()); } } @@ -288,7 +288,7 @@ private void GenerateMaxLengthAttribute(IProperty property) lengthAttribute.AddParameter(_code.Literal(maxLength.Value)); - _sb.AppendLine(lengthAttribute); + _sb.AppendLine(lengthAttribute.ToString()); } } @@ -298,7 +298,7 @@ private void GenerateRequiredAttribute(IProperty property) && property.ClrType.IsNullableType() && !property.IsPrimaryKey()) { - _sb.AppendLine(new AttributeWriter(nameof(RequiredAttribute))); + _sb.AppendLine(new AttributeWriter(nameof(RequiredAttribute)).ToString()); } } @@ -361,7 +361,7 @@ private void GenerateForeignKeyAttribute(INavigation navigation) foreignKeyAttribute.AddParameter($"nameof({navigation.ForeignKey.Properties.First().Name})"); } - _sb.AppendLine(foreignKeyAttribute); + _sb.AppendLine(foreignKeyAttribute.ToString()); } } } @@ -382,7 +382,7 @@ private void GenerateInversePropertyAttribute(INavigation navigation) ? $"nameof({inverseNavigation.DeclaringEntityType.Name}.{inverseNavigation.Name})" : _code.Literal(inverseNavigation.Name)); - _sb.AppendLine(inversePropertyAttribute); + _sb.AppendLine(inversePropertyAttribute.ToString()); } } } diff --git a/src/EFCore.Relational/Migrations/MigrationCommandListBuilder.cs b/src/EFCore.Relational/Migrations/MigrationCommandListBuilder.cs index 22e438edc1d..cabaef37580 100644 --- a/src/EFCore.Relational/Migrations/MigrationCommandListBuilder.cs +++ b/src/EFCore.Relational/Migrations/MigrationCommandListBuilder.cs @@ -65,11 +65,11 @@ public virtual MigrationCommandListBuilder EndCommand(bool suppressTransaction = } /// - /// Appends the given object (as a string) to the command being built. + /// Appends the given string to the command being built. /// - /// The object to append. + /// The string to append. /// This builder so that additional calls can be chained. - public virtual MigrationCommandListBuilder Append([NotNull] object o) + public virtual MigrationCommandListBuilder Append([NotNull] string o) { Check.NotNull(o, nameof(o)); @@ -90,31 +90,31 @@ public virtual MigrationCommandListBuilder AppendLine() } /// - /// Appends the given object (as a string) to the command being built, and then starts a new line. + /// Appends the given string to the command being built, and then starts a new line. /// - /// The object to append. + /// The string to append. /// This builder so that additional calls can be chained. - public virtual MigrationCommandListBuilder AppendLine([NotNull] object o) + public virtual MigrationCommandListBuilder AppendLine([NotNull] string value) { - Check.NotNull(o, nameof(o)); + Check.NotNull(value, nameof(value)); - _commandBuilder.AppendLine(o); + _commandBuilder.AppendLine(value); return this; } /// /// Appends the given object to the command being built as multiple lines of text. That is, - /// each line in the passed object (as a string) is added as a line to the command being built. + /// each line in the passed string is added as a line to the command being built. /// This results in the lines having the correct indentation. /// - /// The object to append. + /// The string to append. /// This builder so that additional calls can be chained. - public virtual MigrationCommandListBuilder AppendLines([NotNull] object o) + public virtual MigrationCommandListBuilder AppendLines([NotNull] string value) { - Check.NotNull(o, nameof(o)); + Check.NotNull(value, nameof(value)); - _commandBuilder.AppendLines(o); + _commandBuilder.AppendLines(value); return this; } diff --git a/src/EFCore.Relational/Query/SqlExpressions/SqlUnaryExpression.cs b/src/EFCore.Relational/Query/SqlExpressions/SqlUnaryExpression.cs index 7aab54a0448..5e8a98b0028 100644 --- a/src/EFCore.Relational/Query/SqlExpressions/SqlUnaryExpression.cs +++ b/src/EFCore.Relational/Query/SqlExpressions/SqlUnaryExpression.cs @@ -75,7 +75,7 @@ public override void Print(ExpressionPrinter expressionPrinter) } else { - expressionPrinter.Append(OperatorType); + expressionPrinter.Append(OperatorType.ToString()); expressionPrinter.Append("("); expressionPrinter.Visit(Operand); expressionPrinter.Append(")"); diff --git a/src/EFCore.Relational/Storage/IRelationalCommandBuilder.cs b/src/EFCore.Relational/Storage/IRelationalCommandBuilder.cs index d08cc0c8bff..41e1e5f2c09 100644 --- a/src/EFCore.Relational/Storage/IRelationalCommandBuilder.cs +++ b/src/EFCore.Relational/Storage/IRelationalCommandBuilder.cs @@ -45,7 +45,7 @@ public interface IRelationalCommandBuilder /// /// The object to be written. /// The same builder instance so that multiple calls can be chained. - IRelationalCommandBuilder Append([NotNull] object value); + IRelationalCommandBuilder Append([NotNull] string value); /// /// Appends a blank line to the command text. diff --git a/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs b/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs index 7100e8da5b6..d3d7fcc7ab5 100644 --- a/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs +++ b/src/EFCore.Relational/Storage/RelationalCommandBuilder.cs @@ -87,7 +87,7 @@ public virtual IRelationalCommandBuilder AddParameter(IRelationalParameter param /// /// The object to be written. /// The same builder instance so that multiple calls can be chained. - public virtual IRelationalCommandBuilder Append(object value) + public virtual IRelationalCommandBuilder Append(string value) { Check.NotNull(value, nameof(value)); diff --git a/src/EFCore.Relational/Storage/RelationalCommandBuilderExtensions.cs b/src/EFCore.Relational/Storage/RelationalCommandBuilderExtensions.cs index edfb5352c21..a24f8f59ca5 100644 --- a/src/EFCore.Relational/Storage/RelationalCommandBuilderExtensions.cs +++ b/src/EFCore.Relational/Storage/RelationalCommandBuilderExtensions.cs @@ -25,7 +25,7 @@ public static class RelationalCommandBuilderExtensions /// The same builder instance so that multiple calls can be chained. public static IRelationalCommandBuilder AppendLine( [NotNull] this IRelationalCommandBuilder commandBuilder, - [NotNull] object value) + [NotNull] string value) { Check.NotNull(commandBuilder, nameof(commandBuilder)); Check.NotNull(value, nameof(value)); @@ -45,13 +45,13 @@ public static IRelationalCommandBuilder AppendLine( /// The same builder instance so that multiple calls can be chained. public static IRelationalCommandBuilder AppendLines( [NotNull] this IRelationalCommandBuilder commandBuilder, - [NotNull] object value, + [NotNull] string value, bool skipFinalNewline = false) { Check.NotNull(commandBuilder, nameof(commandBuilder)); Check.NotNull(value, nameof(value)); - using (var reader = new StringReader(value.ToString())) + using (var reader = new StringReader(value)) { var first = true; string line; diff --git a/src/EFCore/Infrastructure/IndentedStringBuilder.cs b/src/EFCore/Infrastructure/IndentedStringBuilder.cs index 47b52b6440b..154df24989e 100644 --- a/src/EFCore/Infrastructure/IndentedStringBuilder.cs +++ b/src/EFCore/Infrastructure/IndentedStringBuilder.cs @@ -8,6 +8,15 @@ namespace Microsoft.EntityFrameworkCore.Infrastructure { + /// + /// + /// A thin wrapper over that adds indentation to each line built. + /// + /// + /// This type is typically used by database providers (and other extensions). It is generally + /// not used in application code. + /// + /// public class IndentedStringBuilder { private const byte IndentSize = 4; @@ -16,21 +25,29 @@ public class IndentedStringBuilder private readonly StringBuilder _stringBuilder = new StringBuilder(); - public IndentedStringBuilder() - { - } - + /// + /// The current length of the built string. + /// public virtual int Length => _stringBuilder.Length; - public virtual IndentedStringBuilder Append([NotNull] object o) + /// + /// Appends an indent and then the given string to the string being built. + /// + /// The string to append. + /// This builder so that additional calls can be chained. + public virtual IndentedStringBuilder Append([NotNull] string value) { DoIndent(); - _stringBuilder.Append(o); + _stringBuilder.Append(value); return this; } + /// + /// Appends a new line to the string being built. + /// + /// This builder so that additional calls can be chained. public virtual IndentedStringBuilder AppendLine() { AppendLine(string.Empty); @@ -38,10 +55,13 @@ public virtual IndentedStringBuilder AppendLine() return this; } - public virtual IndentedStringBuilder AppendLine([NotNull] object o) + /// + /// Appends an indent, the given string, and a new line to the string being built. + /// + /// The string to append. + /// This builder so that additional calls can be chained. + public virtual IndentedStringBuilder AppendLine([NotNull] string value) { - var value = o.ToString(); - if (value.Length != 0) { DoIndent(); @@ -54,9 +74,15 @@ public virtual IndentedStringBuilder AppendLine([NotNull] object o) return this; } - public virtual IndentedStringBuilder AppendLines([NotNull] object o, bool skipFinalNewline = false) + /// + /// Appends all the lines in the given string, prefixed by the current indent. + /// + /// The string to append. + /// If true, then a terminating new line is not added. + /// This builder so that additional calls can be chained. + public virtual IndentedStringBuilder AppendLines([NotNull] string value, bool skipFinalNewline = false) { - using (var reader = new StringReader(o.ToString())) + using (var reader = new StringReader(value)) { var first = true; string line; @@ -86,13 +112,22 @@ public virtual IndentedStringBuilder AppendLines([NotNull] object o, bool skipFi return this; } + /// + /// Resets this builder ready to build a new string. + /// + /// This builder so that additional calls can be chained. public virtual IndentedStringBuilder Clear() { _stringBuilder.Clear(); + _indent = 0; return this; } + /// + /// Increments the indent. + /// + /// This builder so that additional calls can be chained. public virtual IndentedStringBuilder IncrementIndent() { _indent++; @@ -100,6 +135,10 @@ public virtual IndentedStringBuilder IncrementIndent() return this; } + /// + /// Decrements the indent. + /// + /// This builder so that additional calls can be chained. public virtual IndentedStringBuilder DecrementIndent() { if (_indent > 0) @@ -110,8 +149,16 @@ public virtual IndentedStringBuilder DecrementIndent() return this; } + /// + /// Creates a scoped indenter that will increment the index, then decrement it when disposed. + /// + /// An indenter. public virtual IDisposable Indent() => new Indenter(this); + /// + /// Returns the built string. + /// + /// The built string. public override string ToString() => _stringBuilder.ToString(); private void DoIndent() diff --git a/src/EFCore/Query/EntityShaperExpression.cs b/src/EFCore/Query/EntityShaperExpression.cs index a594c307e96..ab4a4ac2d78 100644 --- a/src/EFCore/Query/EntityShaperExpression.cs +++ b/src/EFCore/Query/EntityShaperExpression.cs @@ -163,7 +163,7 @@ public virtual void Print(ExpressionPrinter expressionPrinter) expressionPrinter.AppendLine(nameof(EntityShaperExpression) + ": "); using (expressionPrinter.Indent()) { - expressionPrinter.AppendLine(EntityType); + expressionPrinter.AppendLine(EntityType.ToString()); expressionPrinter.AppendLine(nameof(ValueBufferExpression) + ": "); using (expressionPrinter.Indent()) { @@ -172,7 +172,7 @@ public virtual void Print(ExpressionPrinter expressionPrinter) } expressionPrinter.Append(nameof(IsNullable) + ": "); - expressionPrinter.AppendLine(IsNullable); + expressionPrinter.AppendLine(IsNullable.ToString()); } } } diff --git a/src/EFCore/Query/ExpressionPrinter.cs b/src/EFCore/Query/ExpressionPrinter.cs index 1233addced9..f368b6d4137 100644 --- a/src/EFCore/Query/ExpressionPrinter.cs +++ b/src/EFCore/Query/ExpressionPrinter.cs @@ -81,37 +81,30 @@ public virtual void VisitCollection( } } - public virtual ExpressionPrinter Append([NotNull] object o) - { - _stringBuilder.Append(o); - return this; - } - public virtual ExpressionPrinter AppendLine() { _stringBuilder.AppendLine(); return this; } - public virtual ExpressionVisitor AppendLine([NotNull] object o) + public virtual ExpressionVisitor AppendLine([NotNull] string value) { - _stringBuilder.AppendLine(o); + _stringBuilder.AppendLine(value); return this; } - public virtual ExpressionPrinter AppendLines([NotNull] object o, bool skipFinalNewline = false) + public virtual ExpressionPrinter AppendLines([NotNull] string value, bool skipFinalNewline = false) { - _stringBuilder.AppendLines(o, skipFinalNewline); + _stringBuilder.AppendLines(value, skipFinalNewline); return this; } public virtual IDisposable Indent() => _stringBuilder.Indent(); - private void Append(string message) => _stringBuilder.Append(message); - - private void AppendLine(string message) + public virtual ExpressionPrinter Append([NotNull] string message) { - _stringBuilder.AppendLine(message); + _stringBuilder.Append(message); + return this; } public virtual string Print( @@ -527,7 +520,7 @@ protected override Expression VisitMemberInit(MemberInitExpression memberInitExp _stringBuilder.Append("new " + memberInitExpression.Type.ShortDisplayName()); - var appendAction = memberInitExpression.Bindings.Count > 1 ? (Action)AppendLine : Append; + var appendAction = memberInitExpression.Bindings.Count > 1 ? (Func)AppendLine : Append; appendAction("{ "); using (_stringBuilder.Indent()) { @@ -615,7 +608,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp || methodArguments.Count < 2 || method.IsEFPropertyMethod(); - var appendAction = isSimpleMethodOrProperty ? (Action)Append : AppendLine; + var appendAction = isSimpleMethodOrProperty ? (Func)Append : AppendLine; if (methodArguments.Count > 0) { @@ -696,7 +689,7 @@ protected override Expression VisitNew(NewExpression newExpression) _stringBuilder.Append("new "); var isComplex = newExpression.Arguments.Count > 1; - var appendAction = isComplex ? (Action)AppendLine : Append; + var appendAction = isComplex ? (Func)AppendLine : Append; var isAnonymousType = newExpression.Type.IsAnonymousType(); if (!isAnonymousType) @@ -748,7 +741,7 @@ protected override Expression VisitNewArray(NewArrayExpression newArrayExpressio Check.NotNull(newArrayExpression, nameof(newArrayExpression)); var isComplex = newArrayExpression.Expressions.Count > 1; - var appendAction = isComplex ? (Action)AppendLine : Append; + var appendAction = isComplex ? (Func)AppendLine : Append; appendAction("new " + newArrayExpression.Type.GetElementType().ShortDisplayName() + "[]"); appendAction("{ "); @@ -786,7 +779,7 @@ protected override Expression VisitParameter(ParameterExpression parameterExpres } Append("namelessParameter{"); - Append(_namelessParameters.IndexOf(parameterExpression)); + Append(_namelessParameters.IndexOf(parameterExpression).ToString()); Append("}"); } else if (parameterName.Contains(".")) @@ -915,7 +908,11 @@ protected override Expression VisitIndex(IndexExpression indexExpression) Visit(indexExpression.Object); _stringBuilder.Append("["); - VisitArguments(indexExpression.Arguments, s => _stringBuilder.Append(s)); + VisitArguments(indexExpression.Arguments, s => + { + _stringBuilder.Append(s); + return null; + }); _stringBuilder.Append("]"); return indexExpression; @@ -992,7 +989,7 @@ protected override Expression VisitExtension(Expression extensionExpression) private void VisitArguments( IReadOnlyList arguments, - Action appendAction, + Func appendAction, string lastSeparator = "", bool areConnected = false) { diff --git a/src/EFCore/Query/ProjectionBindingExpression.cs b/src/EFCore/Query/ProjectionBindingExpression.cs index 5cd4fd741c2..8c7631bddd8 100644 --- a/src/EFCore/Query/ProjectionBindingExpression.cs +++ b/src/EFCore/Query/ProjectionBindingExpression.cs @@ -73,11 +73,11 @@ public virtual void Print(ExpressionPrinter expressionPrinter) expressionPrinter.Append(nameof(ProjectionBindingExpression) + ": "); if (ProjectionMember != null) { - expressionPrinter.Append(ProjectionMember); + expressionPrinter.Append(ProjectionMember.ToString()); } else if (Index != null) { - expressionPrinter.Append(Index); + expressionPrinter.Append(Index.ToString()); } else { diff --git a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs index c599cd46dc9..062efb8a8d9 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TestUtilities/TestRelationalCommandBuilderFactory.cs @@ -54,7 +54,7 @@ public IRelationalCommand Build() Instance.ToString(), Parameters); - public IRelationalCommandBuilder Append(object value) + public IRelationalCommandBuilder Append(string value) { Instance.Append(value); diff --git a/test/EFCore.SqlServer.Tests/SqlServerDatabaseCreatorTest.cs b/test/EFCore.SqlServer.Tests/SqlServerDatabaseCreatorTest.cs index e58d196cdef..507d0fa2a0c 100644 --- a/test/EFCore.SqlServer.Tests/SqlServerDatabaseCreatorTest.cs +++ b/test/EFCore.SqlServer.Tests/SqlServerDatabaseCreatorTest.cs @@ -221,7 +221,7 @@ public IRelationalCommandBuilder AddParameter(IRelationalParameter parameter) public IRelationalCommand Build() => new FakeRelationalCommand(); - public IRelationalCommandBuilder Append(object value) + public IRelationalCommandBuilder Append(string value) { Instance.Append(value);