11// Licensed to the .NET Foundation under one or more agreements.
22// The .NET Foundation licenses this file to you under the MIT license.
33
4+ using System . Linq . Expressions ;
5+ using System . Reflection ;
46using System . Text ;
57using Microsoft . Data . SqlTypes ;
68using Microsoft . EntityFrameworkCore . SqlServer . Internal ;
@@ -25,6 +27,15 @@ public class SqlServerVectorTypeMapping : RelationalTypeMapping
2527
2628 private static readonly VectorComparer _comparerInstance = new ( ) ;
2729
30+ private static readonly MethodInfo _createNullMethod
31+ = typeof ( SqlVector < float > ) . GetMethod ( nameof ( SqlVector < float > . CreateNull ) , [ typeof ( int ) ] ) ! ;
32+
33+ private static readonly ConstructorInfo _constructor
34+ = typeof ( SqlVector < float > ) . GetConstructor ( [ typeof ( ReadOnlyMemory < float > ) ] ) ! ;
35+
36+ private static readonly MethodInfo _memoryImplicitOperator
37+ = typeof ( ReadOnlyMemory < float > ) . GetMethod ( "op_Implicit" , [ typeof ( float [ ] ) ] ) ! ;
38+
2839 // Note that dimensions is mandatory with SQL Server vector.
2940 // However, our scaffolder looks up each type mapping without the facets, to find out whether the scaffolded
3041 // facet happens to be the default (and therefore can be omitted). So we allow constructing a SqlServerVectorTypeMapping
@@ -116,6 +127,38 @@ protected override string GenerateNonNullSqlLiteral(object value)
116127 return builder . ToString ( ) ;
117128 }
118129
130+ /// <summary>
131+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
132+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
133+ /// any release. You should only use it directly in your code with extreme caution and knowing that
134+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
135+ /// </summary>
136+ public override Expression GenerateCodeLiteral ( object value )
137+ {
138+ var vector = ( SqlVector < float > ) value ;
139+
140+ if ( vector . IsNull )
141+ {
142+ return Expression . Call ( _createNullMethod , Expression . Constant ( vector . Length ) ) ;
143+ }
144+
145+ return Expression . New (
146+ _constructor ,
147+ Expression . Convert (
148+ Expression . Constant ( vector . Memory . ToArray ( ) , typeof ( float [ ] ) ) ,
149+ typeof ( ReadOnlyMemory < float > ) ,
150+ _memoryImplicitOperator ) ) ;
151+ }
152+
153+ /// <summary>
154+ /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
155+ /// the same compatibility standards as public APIs. It may be changed or removed without notice in
156+ /// any release. You should only use it directly in your code with extreme caution and knowing that
157+ /// doing so can result in application failures when updating to a new Entity Framework Core release.
158+ /// </summary>
159+ public override object ? GetDefaultProviderValue ( )
160+ => Size is int dimensions ? new SqlVector < float > ( new float [ dimensions ] ) : null ;
161+
119162 private sealed class VectorComparer ( ) : ValueComparer < SqlVector < float > > (
120163 ( x , y ) => CalculateEquality ( x , y ) ,
121164 v => CalculateHashCode ( v ) ,
0 commit comments