|
4 | 4 | using System; |
5 | 5 | using System.Collections.Generic; |
6 | 6 | using System.Data.Common; |
| 7 | +using System.IO; |
7 | 8 | using System.Linq; |
| 9 | +using System.Linq.Expressions; |
8 | 10 | using System.Reflection; |
| 11 | +using System.Text; |
9 | 12 | using JetBrains.Annotations; |
10 | 13 | using Microsoft.EntityFrameworkCore; |
11 | 14 | using Microsoft.EntityFrameworkCore.ChangeTracking; |
@@ -130,6 +133,37 @@ protected override void ConfigureParameter(DbParameter parameter) |
130 | 133 | public override MethodInfo GetDataReaderMethod() |
131 | 134 | => _getString; |
132 | 135 |
|
| 136 | + /// <summary> |
| 137 | + /// Customizes the data reader expression for JSON types. |
| 138 | + /// MySQL stores JSON as strings, but EF Core expects MemoryStream for complex JSON types. |
| 139 | + /// This method creates an expression that converts the string to a MemoryStream containing UTF-8 encoded bytes. |
| 140 | + /// </summary> |
| 141 | + public override Expression CustomizeDataReaderExpression(Expression expression) |
| 142 | + { |
| 143 | + // For JSON complex types, EF Core expects a MemoryStream containing JSON data. |
| 144 | + // MySQL returns JSON as strings, so we need to convert: string -> byte[] -> MemoryStream |
| 145 | + |
| 146 | + if (expression.Type == typeof(string)) |
| 147 | + { |
| 148 | + // Convert string to MemoryStream: new MemoryStream(Encoding.UTF8.GetBytes(stringValue)) |
| 149 | + var getBytes = typeof(System.Text.Encoding).GetProperty(nameof(System.Text.Encoding.UTF8))! |
| 150 | + .GetMethod!; |
| 151 | + var getBytesMethod = typeof(System.Text.Encoding).GetMethod( |
| 152 | + nameof(System.Text.Encoding.GetBytes), |
| 153 | + new[] { typeof(string) })!; |
| 154 | + var memoryStreamCtor = typeof(System.IO.MemoryStream).GetConstructor(new[] { typeof(byte[]) })!; |
| 155 | + |
| 156 | + return Expression.New( |
| 157 | + memoryStreamCtor, |
| 158 | + Expression.Call( |
| 159 | + Expression.Property(null, getBytes), |
| 160 | + getBytesMethod, |
| 161 | + expression)); |
| 162 | + } |
| 163 | + |
| 164 | + return base.CustomizeDataReaderExpression(expression); |
| 165 | + } |
| 166 | + |
133 | 167 | void IMySqlCSharpRuntimeAnnotationTypeMappingCodeGenerator.Create( |
134 | 168 | CSharpRuntimeAnnotationCodeGeneratorParameters codeGeneratorParameters, |
135 | 169 | CSharpRuntimeAnnotationCodeGeneratorDependencies codeGeneratorDependencies) |
|
0 commit comments