diff --git a/src/EFCore.Design/Design/Internal/CSharpHelper.cs b/src/EFCore.Design/Design/Internal/CSharpHelper.cs
index 9ee6e914bc6..562fb412e2b 100644
--- a/src/EFCore.Design/Design/Internal/CSharpHelper.cs
+++ b/src/EFCore.Design/Design/Internal/CSharpHelper.cs
@@ -737,6 +737,79 @@ public virtual string Literal(object?[,] values)
return builder.ToString();
}
+ ///
+ /// 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.
+ ///
+ public virtual string Literal(List 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();
+ }
+
///
/// 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
@@ -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)
{
diff --git a/test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs b/test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs
index d03c74c1aa9..2fc765dab8f 100644
--- a/test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs
+++ b/test/EFCore.Design.Tests/Design/Internal/CSharpHelperTest.cs
@@ -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(),
+ @"new List()");
+
+ [ConditionalFact]
+ public void Literal_works_when_list_with_single_element()
+ => Literal_works(
+ new List { "one" },
+ @"new List { ""one"" }");
+
+ [ConditionalFact]
+ public void Literal_works_when_list_of_mixed_objects()
+ => Literal_works(
+ new List