@@ -369,6 +369,8 @@ private string GetOrCreate(
369369 Create ( column , tableParameters ) ;
370370 }
371371
372+ CreateJsonElements ( table , tableParameters ) ;
373+
372374 CreateAnnotations (
373375 table ,
374376 Generate ,
@@ -406,6 +408,8 @@ private string Create(
406408 Create ( column , tableParameters ) ;
407409 }
408410
411+ CreateJsonElements ( table , tableParameters ) ;
412+
409413 CreateAnnotations (
410414 table ,
411415 Generate ,
@@ -449,6 +453,8 @@ private string GetOrCreate(
449453 Create ( column , viewParameters ) ;
450454 }
451455
456+ CreateJsonElements ( view , viewParameters ) ;
457+
452458 CreateAnnotations (
453459 view ,
454460 Generate ,
@@ -469,6 +475,221 @@ private string GetOrCreate(
469475 public virtual void Generate ( IView view , CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
470476 => GenerateSimpleAnnotations ( parameters ) ;
471477
478+ private void CreateJsonElements (
479+ ITableBase table ,
480+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
481+ {
482+ foreach ( var column in table . Columns )
483+ {
484+ if ( column . JsonElement == null )
485+ {
486+ continue ;
487+ }
488+
489+ var code = Dependencies . CSharpHelper ;
490+ var mainBuilder = parameters . MainBuilder ;
491+ AddNamespace ( typeof ( RelationalJsonObject ) , parameters . Namespaces ) ;
492+
493+ var columnVariable = parameters . ScopeVariables . TryGetValue ( column , out var cv )
494+ ? cv
495+ : $ "{ parameters . TargetName } .FindColumn({ code . Literal ( column . Name ) } )!";
496+ var elementVariable = CreateJsonElement ( column . JsonElement , columnVariable , parameters ) ;
497+
498+ mainBuilder . AppendLine ( $ "{ columnVariable } .JsonElement = { elementVariable } ;") ;
499+ }
500+ }
501+
502+ private void CreateJsonElementMappings (
503+ ITableMappingBase tableMapping ,
504+ string tableMappingVariable ,
505+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
506+ {
507+ foreach ( var column in tableMapping . Table . Columns )
508+ {
509+ if ( column . JsonElement != null )
510+ {
511+ CreateJsonElementMappings ( column . JsonElement , tableMapping , tableMappingVariable , parameters ) ;
512+ }
513+ }
514+ }
515+
516+ private void CreateJsonElementMappings (
517+ IRelationalJsonElement element ,
518+ ITableMappingBase tableMapping ,
519+ string tableMappingVariable ,
520+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
521+ {
522+ if ( parameters . ScopeVariables . TryGetValue ( element , out var elementVariable ) )
523+ {
524+ foreach ( var mapping in element . PropertyMappings . Where ( m => ReferenceEquals ( m . TableMapping , tableMapping ) ) )
525+ {
526+ parameters . MainBuilder
527+ . Append ( "RelationalModel.CreateJsonElementMapping(" )
528+ . Append ( GetPropertyBaseAccess ( mapping . Property , parameters ) )
529+ . Append ( ", " )
530+ . Append ( elementVariable )
531+ . Append ( ", " )
532+ . Append ( tableMappingVariable )
533+ . AppendLine ( ");" ) ;
534+ }
535+ }
536+
537+ switch ( element )
538+ {
539+ case IRelationalJsonObject jsonObject :
540+ foreach ( var child in jsonObject . Properties )
541+ {
542+ CreateJsonElementMappings ( child , tableMapping , tableMappingVariable , parameters ) ;
543+ }
544+
545+ break ;
546+ case IRelationalJsonArray jsonArray :
547+ CreateJsonElementMappings ( jsonArray . ElementType , tableMapping , tableMappingVariable , parameters ) ;
548+ break ;
549+ }
550+ }
551+
552+ private string GetPropertyBaseAccess (
553+ IPropertyBase propertyBase ,
554+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
555+ {
556+ var code = Dependencies . CSharpHelper ;
557+ var declaringTypeAccess = GetTypeBaseAccess ( propertyBase . DeclaringType , parameters ) ;
558+
559+ return propertyBase switch
560+ {
561+ IProperty property => $ "{ declaringTypeAccess } .FindProperty({ code . Literal ( property . Name ) } )!",
562+ IComplexProperty complexProperty => $ "{ declaringTypeAccess } .FindComplexProperty({ code . Literal ( complexProperty . Name ) } )!",
563+ INavigation navigation => $ "{ declaringTypeAccess } .FindNavigation({ code . Literal ( navigation . Name ) } )!",
564+ _ => throw new UnreachableException ( )
565+ } ;
566+ }
567+
568+ private string GetTypeBaseAccess (
569+ ITypeBase typeBase ,
570+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
571+ {
572+ var code = Dependencies . CSharpHelper ;
573+ if ( parameters . ScopeVariables . TryGetValue ( typeBase , out var variable ) )
574+ {
575+ return variable ;
576+ }
577+
578+ return typeBase switch
579+ {
580+ IEntityType entityType => $ "FindEntityType({ code . Literal ( entityType . Name ) } )!",
581+ IComplexType complexType
582+ => $ "{ GetTypeBaseAccess ( complexType . ComplexProperty . DeclaringType , parameters ) } .FindComplexProperty({ code . Literal ( complexType . ComplexProperty . Name ) } )!.ComplexType",
583+ _ => throw new UnreachableException ( )
584+ } ;
585+ }
586+
587+ private string CreateJsonElement (
588+ IRelationalJsonElement element ,
589+ string columnVariable ,
590+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
591+ {
592+ var parentLiteral = element . ParentElement != null && parameters . ScopeVariables . TryGetValue ( element . ParentElement , out var pv )
593+ ? pv
594+ : "null" ;
595+
596+ return element switch
597+ {
598+ IRelationalJsonObject jsonObject => CreateJsonObject ( jsonObject , columnVariable , parentLiteral , parameters ) ,
599+ IRelationalJsonArray jsonArray => CreateJsonArray ( jsonArray , columnVariable , parentLiteral , parameters ) ,
600+ RelationalJsonScalar jsonScalar => CreateJsonProperty ( jsonScalar , columnVariable , parentLiteral , parameters ) ,
601+ _ => throw new UnreachableException ( )
602+ } ;
603+ }
604+
605+ private string CreateJsonObject (
606+ IRelationalJsonObject jsonObject ,
607+ string columnVariable ,
608+ string parentLiteral ,
609+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
610+ {
611+ var code = Dependencies . CSharpHelper ;
612+ var mainBuilder = parameters . MainBuilder ;
613+ var variable = code . Identifier ( ( jsonObject . PropertyName ?? "element" ) + "JsonObject" , jsonObject , parameters . ScopeObjects , capitalize : false ) ;
614+ parameters . ScopeVariables [ jsonObject ] = variable ;
615+
616+ mainBuilder . Append ( $ "var { variable } = new RelationalJsonObject(") ;
617+ AppendJsonConstructorArgs ( jsonObject , columnVariable , parentLiteral , mainBuilder , code ) ;
618+ mainBuilder . AppendLine ( ");" ) ;
619+
620+ foreach ( var child in jsonObject . Properties )
621+ {
622+ var childVariable = CreateJsonElement ( child , columnVariable , parameters ) ;
623+ mainBuilder . AppendLine ( $ "{ variable } .AddProperty({ childVariable } );") ;
624+ }
625+
626+ return variable ;
627+ }
628+
629+ private string CreateJsonArray (
630+ IRelationalJsonArray jsonArray ,
631+ string columnVariable ,
632+ string parentLiteral ,
633+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
634+ {
635+ var code = Dependencies . CSharpHelper ;
636+ var mainBuilder = parameters . MainBuilder ;
637+
638+ var variable = code . Identifier ( ( jsonArray . PropertyName ?? "array" ) + "JsonArray" , jsonArray , parameters . ScopeObjects , capitalize : false ) ;
639+ parameters . ScopeVariables [ jsonArray ] = variable ;
640+
641+ mainBuilder . Append ( $ "var { variable } = new RelationalJsonArray(") ;
642+ AppendJsonConstructorArgs ( jsonArray , columnVariable , parentLiteral , mainBuilder , code ) ;
643+ mainBuilder . AppendLine ( ");" ) ;
644+
645+ var elementTypeVariable = CreateJsonElement ( jsonArray . ElementType , columnVariable , parameters ) ;
646+ mainBuilder . AppendLine ( $ "{ variable } .ElementType = { elementTypeVariable } ;") ;
647+
648+ return variable ;
649+ }
650+
651+ private string CreateJsonProperty (
652+ RelationalJsonScalar jsonScalar ,
653+ string columnVariable ,
654+ string parentLiteral ,
655+ CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
656+ {
657+ var code = Dependencies . CSharpHelper ;
658+ var mainBuilder = parameters . MainBuilder ;
659+ var variable = code . Identifier ( ( jsonScalar . PropertyName ?? "scalar" ) + "JsonScalar" , jsonScalar , parameters . ScopeObjects , capitalize : false ) ;
660+ parameters . ScopeVariables [ jsonScalar ] = variable ;
661+
662+ mainBuilder . Append ( $ "var { variable } = new RelationalJsonScalar(") ;
663+ AppendJsonConstructorArgs ( jsonScalar , columnVariable , parentLiteral , mainBuilder , code ) ;
664+ mainBuilder . AppendLine ( ");" ) ;
665+
666+ return variable ;
667+ }
668+
669+ private static void AppendJsonConstructorArgs (
670+ IRelationalJsonElement element ,
671+ string columnVariable ,
672+ string parentLiteral ,
673+ IndentedStringBuilder builder ,
674+ ICSharpHelper code )
675+ {
676+ if ( element . ParentElement is IRelationalJsonArray )
677+ {
678+ // (parent, isNullable) — array type
679+ builder . Append ( $ "{ parentLiteral } , { code . Literal ( element . IsNullable ) } ") ;
680+ }
681+ else if ( element . ParentElement is IRelationalJsonObject )
682+ {
683+ // (name, parent, isNullable) — object property
684+ builder . Append ( $ "{ code . Literal ( element . PropertyName ! ) } , { parentLiteral } , { code . Literal ( element . IsNullable ) } ") ;
685+ }
686+ else
687+ {
688+ // (column, isNullable) — root element
689+ builder . Append ( $ "{ columnVariable } , { code . Literal ( element . IsNullable ) } ") ;
690+ }
691+ }
692+
472693 private string GetOrCreate (
473694 ISqlQuery sqlQuery ,
474695 CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
@@ -1182,6 +1403,8 @@ private void Create(
11821403 . Append ( $ "{ typeBaseVariable } .FindProperty({ code . Literal ( columnMapping . Property . Name ) } )!, ")
11831404 . Append ( tableMappingVariable ) . AppendLine ( ");" ) ;
11841405 }
1406+
1407+ CreateJsonElementMappings ( tableMapping , tableMappingVariable , parameters ) ;
11851408 }
11861409
11871410 /// <summary>
@@ -1234,6 +1457,8 @@ private void Create(
12341457 . Append ( tableMappingVariable ) . AppendLine ( ");" ) ;
12351458 }
12361459
1460+ CreateJsonElementMappings ( tableMapping , tableMappingVariable , parameters ) ;
1461+
12371462 if ( tableMapping == table . EntityTypeMappings . Last ( ) )
12381463 {
12391464 foreach ( var uniqueConstraint in table . UniqueConstraints )
@@ -1302,6 +1527,8 @@ private void Create(
13021527 . Append ( $ "{ typeBaseVariable } .FindProperty({ code . Literal ( columnMapping . Property . Name ) } )!, ")
13031528 . Append ( viewMappingVariable ) . AppendLine ( ");" ) ;
13041529 }
1530+
1531+ CreateJsonElementMappings ( viewMapping , viewMappingVariable , parameters ) ;
13051532 }
13061533
13071534 /// <summary>
@@ -1355,6 +1582,8 @@ private void Create(
13551582 . Append ( $ "{ typeBaseVariable } .FindProperty({ code . Literal ( columnMapping . Property . Name ) } )!, ")
13561583 . Append ( sqlQueryMappingVariable ) . AppendLine ( ");" ) ;
13571584 }
1585+
1586+ CreateJsonElementMappings ( sqlQueryMapping , sqlQueryMappingVariable , parameters ) ;
13581587 }
13591588
13601589 /// <summary>
@@ -1410,6 +1639,8 @@ private void Create(
14101639 . Append ( $ "{ typeBaseVariable } .FindProperty({ code . Literal ( columnMapping . Property . Name ) } )!, ")
14111640 . Append ( functionMappingVariable ) . AppendLine ( ");" ) ;
14121641 }
1642+
1643+ CreateJsonElementMappings ( functionMapping , functionMappingVariable , parameters ) ;
14131644 }
14141645
14151646 /// <summary>
@@ -2078,6 +2309,7 @@ public override void Generate(IProperty property, CSharpRuntimeAnnotationCodeGen
20782309 annotations . Remove ( RelationalAnnotationNames . UpdateStoredProcedureParameterMappings ) ;
20792310 annotations . Remove ( RelationalAnnotationNames . UpdateStoredProcedureResultColumnMappings ) ;
20802311 annotations . Remove ( RelationalAnnotationNames . DefaultColumnMappings ) ;
2312+ annotations . Remove ( RelationalAnnotationNames . JsonElementMappings ) ;
20812313 }
20822314 else
20832315 {
@@ -2110,6 +2342,40 @@ public override void Generate(IProperty property, CSharpRuntimeAnnotationCodeGen
21102342 base . Generate ( property , parameters ) ;
21112343 }
21122344
2345+ /// <inheritdoc />
2346+ public override void Generate ( INavigation navigation , CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
2347+ {
2348+ if ( parameters . IsRuntime )
2349+ {
2350+ var annotations = parameters . Annotations ;
2351+ annotations . Remove ( RelationalAnnotationNames . TableColumnMappings ) ;
2352+ annotations . Remove ( RelationalAnnotationNames . ViewColumnMappings ) ;
2353+ annotations . Remove ( RelationalAnnotationNames . SqlQueryColumnMappings ) ;
2354+ annotations . Remove ( RelationalAnnotationNames . FunctionColumnMappings ) ;
2355+ annotations . Remove ( RelationalAnnotationNames . DefaultColumnMappings ) ;
2356+ annotations . Remove ( RelationalAnnotationNames . JsonElementMappings ) ;
2357+ }
2358+
2359+ base . Generate ( navigation , parameters ) ;
2360+ }
2361+
2362+ /// <inheritdoc />
2363+ public override void Generate ( IComplexProperty complexProperty , CSharpRuntimeAnnotationCodeGeneratorParameters parameters )
2364+ {
2365+ if ( parameters . IsRuntime )
2366+ {
2367+ var annotations = parameters . Annotations ;
2368+ annotations . Remove ( RelationalAnnotationNames . TableColumnMappings ) ;
2369+ annotations . Remove ( RelationalAnnotationNames . ViewColumnMappings ) ;
2370+ annotations . Remove ( RelationalAnnotationNames . SqlQueryColumnMappings ) ;
2371+ annotations . Remove ( RelationalAnnotationNames . FunctionColumnMappings ) ;
2372+ annotations . Remove ( RelationalAnnotationNames . DefaultColumnMappings ) ;
2373+ annotations . Remove ( RelationalAnnotationNames . JsonElementMappings ) ;
2374+ }
2375+
2376+ base . Generate ( complexProperty , parameters ) ;
2377+ }
2378+
21132379 private void Create (
21142380 IRelationalPropertyOverrides overrides ,
21152381 string overridesVariable ,
0 commit comments