Skip to content

Commit

Permalink
Add support for CSharpHelper for List literals (#28212)
Browse files Browse the repository at this point in the history
* Add support for CSharpHelper for List literals

Fixes #19274

Also relates to npgsql/efcore.pg#2402

* Fixes from review comments
  • Loading branch information
yinzara authored Jun 27, 2022
1 parent 36b9aa3 commit f72888f
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
78 changes: 78 additions & 0 deletions src/EFCore.Design/Design/Internal/CSharpHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,79 @@ public virtual string Literal(object?[,] values)
return builder.ToString();
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual string Literal<T>(List<T> values, bool vertical = false)
=> List(typeof(T), values, vertical);

private string List(Type type, IEnumerable values, bool vertical = false)
{
var builder = new IndentedStringBuilder();

builder.Append("new List<")
.Append(Reference(type))
.Append(">");

var first = true;
foreach (var value in values)
{
if (first)
{
builder.Append(" {");
if (vertical)
{
builder.AppendLine();
builder.IncrementIndent();
}
else
{
builder.Append(" ");
}
first = false;
}
else
{
builder.Append(",");

if (vertical)
{
builder.AppendLine();
}
else
{
builder.Append(" ");
}
}

builder.Append(UnknownLiteral(value));
}

if (first)
{
builder.Append("()");
}
else
{
if (vertical)
{
builder.AppendLine();
builder.DecrementIndent();
}
else
{
builder.Append(" ");
}

builder.Append("}");
}

return builder.ToString();
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
Expand Down Expand Up @@ -844,6 +917,11 @@ public virtual string UnknownLiteral(object? value)
return Array(literalType.GetElementType()!, array);
}

if (value is IList list && value.GetType().IsGenericType && value.GetType().GetGenericTypeDefinition() == typeof(List<>))
{
return List(value.GetType().GetGenericArguments()[0], list);
}

var mapping = _typeMappingSource.FindMapping(literalType);
if (mapping != null)
{
Expand Down
24 changes: 24 additions & 0 deletions test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,30 @@ public void Literal_works_when_many_ByteArray()
new byte[] { 1, 2 },
"new byte[] { 1, 2 }");

[ConditionalFact]
public void Literal_works_when_empty_list()
=> Literal_works(
new List<string>(),
@"new List<string>()");

[ConditionalFact]
public void Literal_works_when_list_with_single_element()
=> Literal_works(
new List<string> { "one" },
@"new List<string> { ""one"" }");

[ConditionalFact]
public void Literal_works_when_list_of_mixed_objects()
=> Literal_works(
new List<object> { 1, "two" },
@"new List<object> { 1, ""two"" }");

[ConditionalFact]
public void Literal_works_when_list_with_ctor_arguments()
=> Literal_works(
new List<string>(new [] { "one" }) { "two", "three" },
@"new List<string> { ""one"", ""two"", ""three"" }");

[ConditionalFact]
public void Literal_works_when_multiline_string()
=> Literal_works(
Expand Down

0 comments on commit f72888f

Please sign in to comment.