@@ -214,125 +214,9 @@ protected override ShapedQueryExpression TranslateElementAtOrDefault(
214214
215215 protected override ShapedQueryExpression TransformJsonQueryToTable ( JsonQueryExpression jsonQueryExpression )
216216 {
217- // Calculate the table alias for the JSON_TABLE function based on the last named path segment
218- // (or the JSON column name if there are none)
219- var lastNamedPathSegment = jsonQueryExpression . Path . LastOrDefault ( ps => ps . PropertyName is not null ) ;
220- var tableAlias = _sqlAliasManager . GenerateTableAlias (
221- lastNamedPathSegment . PropertyName ?? jsonQueryExpression . JsonColumn . Name ) ;
222-
223- // We now add all of the projected entity's properties and navigations into the JSON_TABLE's COLUMNS clause
224- var columnInfos = new List < MySqlJsonTableExpression . ColumnInfo > ( ) ;
225-
226- // We're only interested in properties which actually exist in the JSON, filter out uninteresting shadow keys
227- foreach ( var property in jsonQueryExpression . StructuralType . GetPropertiesInHierarchy ( ) )
228- {
229- if ( property . GetJsonPropertyName ( ) is string jsonPropertyName )
230- {
231- var typeMapping = property . GetRelationalTypeMapping ( ) ;
232-
233- columnInfos . Add (
234- new MySqlJsonTableExpression . ColumnInfo (
235- Name : jsonPropertyName ,
236- TypeMapping : typeMapping ,
237- // Build path for this property: $[0]
238- Path : [ new PathSegment ( _sqlExpressionFactory . Constant ( 0 , _typeMappingSource . FindMapping ( typeof ( int ) ) ) ) ] ,
239- AsJson : false ) ) ;
240- }
241- }
242-
243- // Add navigations to owned entities mapped to JSON
244- switch ( jsonQueryExpression . StructuralType )
245- {
246- case IEntityType entityType :
247- foreach ( var navigation in entityType . GetNavigationsInHierarchy ( )
248- . Where ( n => n . ForeignKey . IsOwnership
249- && n . TargetEntityType . IsMappedToJson ( )
250- && n . ForeignKey . PrincipalToDependent == n ) )
251- {
252- var jsonNavigationName = navigation . TargetEntityType . GetJsonPropertyName ( ) ;
253- Check . DebugAssert ( jsonNavigationName is not null , $ "No JSON property name for navigation { navigation . Name } ") ;
254-
255- columnInfos . Add (
256- new MySqlJsonTableExpression . ColumnInfo (
257- Name : jsonNavigationName ,
258- TypeMapping : jsonQueryExpression . JsonColumn . TypeMapping ! ,
259- Path : [ new PathSegment ( _sqlExpressionFactory . Constant ( 0 , _typeMappingSource . FindMapping ( typeof ( int ) ) ) ) ] ,
260- AsJson : true ) ) ;
261- }
262- break ;
263-
264- case IComplexType complexType :
265- foreach ( var complexProperty in complexType . GetComplexProperties ( ) )
266- {
267- var jsonPropertyName = complexProperty . ComplexType . GetJsonPropertyName ( ) ;
268- Check . DebugAssert ( jsonPropertyName is not null , $ "No JSON property name for complex property { complexProperty . Name } ") ;
269-
270- columnInfos . Add (
271- new MySqlJsonTableExpression . ColumnInfo (
272- Name : jsonPropertyName ,
273- TypeMapping : jsonQueryExpression . JsonColumn . TypeMapping ! ,
274- Path : [ new PathSegment ( _sqlExpressionFactory . Constant ( 0 , _typeMappingSource . FindMapping ( typeof ( int ) ) ) ) ] ,
275- AsJson : true ) ) ;
276- }
277- break ;
278-
279- default :
280- throw new UnreachableException ( ) ;
281- }
282-
283- // MySQL JSON_TABLE requires the nested JSON document - it does not accept a path within a containing JSON document
284- // in the same way as SQL Server OPENJSON. So we wrap JSON_TABLE around a JsonScalarExpression which will extract
285- // the nested document.
286- var jsonScalarExpression = new JsonScalarExpression (
287- jsonQueryExpression . JsonColumn ,
288- jsonQueryExpression . Path ,
289- typeof ( string ) ,
290- jsonQueryExpression . JsonColumn . TypeMapping ,
291- jsonQueryExpression . IsNullable ) ;
292-
293- // Construct the JSON_TABLE expression with the JsonScalarExpression
294- var jsonTableExpression = new MySqlJsonTableExpression (
295- tableAlias ,
296- jsonScalarExpression ,
297- [ new PathSegment ( _sqlExpressionFactory . Constant ( "*" , RelationalTypeMapping . NullMapping ) ) ] ,
298- [ .. columnInfos ] ) ;
299-
300- // Create the key column for ordering (JSON_TABLE returns a 'key' column for array elements)
301- var keyColumnTypeMapping = _typeMappingSource . FindMapping ( typeof ( uint ) ) ! ;
302-
303- #pragma warning disable EF1001 // Internal EF Core API usage.
304- var selectExpression = new SelectExpression (
305- [ jsonTableExpression ] ,
306- new ColumnExpression (
307- "key" ,
308- tableAlias ,
309- typeof ( uint ) ,
310- keyColumnTypeMapping ,
311- nullable : false ) ,
312- identifier : [ ( new ColumnExpression ( "key" , tableAlias , typeof ( uint ) , keyColumnTypeMapping , nullable : false ) , keyColumnTypeMapping . Comparer ) ] ,
313- _sqlAliasManager ) ;
314- #pragma warning restore EF1001 // Internal EF Core API usage.
315-
316- // Add ordering by the key column to maintain array order
317- selectExpression . AppendOrdering (
318- new OrderingExpression (
319- selectExpression . CreateColumnExpression (
320- jsonTableExpression ,
321- "key" ,
322- typeof ( uint ) ,
323- typeMapping : keyColumnTypeMapping ,
324- columnNullable : false ) ,
325- ascending : true ) ) ;
326-
327- return new ShapedQueryExpression (
328- selectExpression ,
329- new RelationalStructuralTypeShaperExpression (
330- jsonQueryExpression . StructuralType ,
331- new ProjectionBindingExpression (
332- selectExpression ,
333- new ProjectionMember ( ) ,
334- typeof ( ValueBuffer ) ) ,
335- false ) ) ;
217+ // Call the base implementation which will handle the transformation using the default approach
218+ // This should work now that we have proper JSON_TABLE support
219+ return base . TransformJsonQueryToTable ( jsonQueryExpression ) ;
336220 }
337221
338222 protected override ShapedQueryExpression TranslatePrimitiveCollection ( SqlExpression sqlExpression , IProperty property , string tableAlias )
0 commit comments