Skip to content

Commit 948f768

Browse files
Copilotrenemadsen
andcommitted
Fix: Add CustomizeDataReaderExpression to convert string to MemoryStream
MySQL stores JSON as strings, but EF Core expects MemoryStream for JSON complex types. Added CustomizeDataReaderExpression override to convert string to MemoryStream. Also kept GetDataReaderMethod override to use GetString. This fixes the "No coercion operator is defined between types 'System.String' and 'System.IO.MemoryStream'" error. Co-authored-by: renemadsen <76994+renemadsen@users.noreply.github.com>
1 parent 0300f55 commit 948f768

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

src/EFCore.MySql/Storage/Internal/MySqlJsonTypeMapping.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Data.Common;
7+
using System.IO;
78
using System.Linq;
9+
using System.Linq.Expressions;
810
using System.Reflection;
11+
using System.Text;
912
using JetBrains.Annotations;
1013
using Microsoft.EntityFrameworkCore;
1114
using Microsoft.EntityFrameworkCore.ChangeTracking;
@@ -130,6 +133,37 @@ protected override void ConfigureParameter(DbParameter parameter)
130133
public override MethodInfo GetDataReaderMethod()
131134
=> _getString;
132135

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+
133167
void IMySqlCSharpRuntimeAnnotationTypeMappingCodeGenerator.Create(
134168
CSharpRuntimeAnnotationCodeGeneratorParameters codeGeneratorParameters,
135169
CSharpRuntimeAnnotationCodeGeneratorDependencies codeGeneratorDependencies)

0 commit comments

Comments
 (0)