@@ -737,6 +737,71 @@ public virtual string Literal(object?[,] values)
737737 return builder . ToString ( ) ;
738738 }
739739
740+ /// <summary>
741+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
742+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
743+ /// any release. You should only use it directly in your code with extreme caution and knowing that
744+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
745+ /// </summary>
746+ public virtual string Literal < T > ( IList < T > values , bool vertical = false )
747+ => List ( typeof ( T ) , values , vertical ) ;
748+
749+ private string List ( Type type , IEnumerable values , bool vertical = false )
750+ {
751+ var builder = new IndentedStringBuilder ( ) ;
752+
753+ builder . Append ( "new List<" )
754+ . Append ( Reference ( type ) )
755+ . Append ( "> {" ) ;
756+
757+ var first = true ;
758+ foreach ( var value in values )
759+ {
760+ if ( first )
761+ {
762+ if ( vertical )
763+ {
764+ builder . AppendLine ( ) ;
765+ builder . IncrementIndent ( ) ;
766+ }
767+ else
768+ {
769+ builder . Append ( " " ) ;
770+ }
771+ first = false ;
772+ }
773+ else
774+ {
775+ builder . Append ( "," ) ;
776+
777+ if ( vertical )
778+ {
779+ builder . AppendLine ( ) ;
780+ }
781+ else
782+ {
783+ builder . Append ( " " ) ;
784+ }
785+ }
786+
787+ builder . Append ( UnknownLiteral ( value ) ) ;
788+ }
789+
790+ if ( vertical )
791+ {
792+ builder . AppendLine ( ) ;
793+ builder . DecrementIndent ( ) ;
794+ }
795+ else
796+ {
797+ builder . Append ( " " ) ;
798+ }
799+
800+ builder . Append ( "}" ) ;
801+
802+ return builder . ToString ( ) ;
803+ }
804+
740805 /// <summary>
741806 /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
742807 /// the same compatibility standards as public APIs. It may be changed or removed without notice in
@@ -844,6 +909,11 @@ public virtual string UnknownLiteral(object? value)
844909 return Array ( literalType . GetElementType ( ) ! , array ) ;
845910 }
846911
912+ if ( value is IList list && value . GetType ( ) . IsGenericType && value . GetType ( ) . GetGenericTypeDefinition ( ) == typeof ( List < > ) )
913+ {
914+ return List ( value . GetType ( ) . GetGenericArguments ( ) [ 0 ] , list ) ;
915+ }
916+
847917 var mapping = _typeMappingSource . FindMapping ( literalType ) ;
848918 if ( mapping != null )
849919 {
@@ -878,6 +948,35 @@ private bool HandleExpression(Expression expression, StringBuilder builder, bool
878948
879949 HandleList ( ( ( NewArrayExpression ) expression ) . Expressions , builder , simple : true ) ;
880950
951+ builder
952+ . Append ( " }" ) ;
953+
954+ return true ;
955+ case ExpressionType . ListInit :
956+ var listExpr = ( ListInitExpression ) expression ;
957+ if ( listExpr . Initializers . Any ( i => i . Arguments . Count != 1 ) )
958+ {
959+ // If there is an initializer with more than one argument we can't make a literal cleanly
960+ return false ;
961+ }
962+
963+ builder
964+ . Append ( "new " )
965+ . Append ( Reference ( expression . Type ) ) ;
966+
967+ if ( listExpr . NewExpression . Arguments . Count > 0 && ! HandleArguments ( listExpr . NewExpression . Arguments , builder ) )
968+ {
969+ return false ;
970+ }
971+
972+ builder
973+ . Append ( " { " ) ;
974+
975+ if ( ! HandleList ( listExpr . Initializers . Select ( i => i . Arguments . First ( ) ) , builder , simple : true ) )
976+ {
977+ return false ;
978+ }
979+
881980 builder
882981 . Append ( " }" ) ;
883982
0 commit comments