Skip to content

Commit 1298fde

Browse files
authored
Merge pull request #1191 from progressonderwijs/fons/json_nulls
Added standaard configuration parm for configuring the serialization of null-properties when reading JSON from SQL query.
2 parents 6b11790 + f4ba7ec commit 1298fde

File tree

5 files changed

+82
-7
lines changed

5 files changed

+82
-7
lines changed

src/ProgressOnderwijsUtils/Data/ParameterizedSqlObjectMapper.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Buffers;
22
using System.ComponentModel.DataAnnotations.Schema;
33
using System.Text.Json;
4+
using System.Text.Json.Serialization;
45
using Microsoft.EntityFrameworkCore.Query;
56

67
// ReSharper disable ConvertToUsingDeclaration
@@ -69,8 +70,8 @@ public static void ExecuteNonQuery(this ParameterizedSql sql, SqlConnection sqlC
6970
where T : IWrittenImplicitly
7071
=> q.OfPocos<T>().Execute(sqlConn);
7172

72-
public static void ReadJson(this ParameterizedSql q, SqlConnection sqlConn, IBufferWriter<byte> buffer, JsonWriterOptions options)
73-
=> q.OfJson().Execute(sqlConn, buffer, options);
73+
public static void ReadJson(this ParameterizedSql q, SqlConnection sqlConn, IBufferWriter<byte> buffer, JsonWriterOptions options, JsonIgnoreCondition defaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)
74+
=> q.OfJson().Execute(sqlConn, buffer, options, defaultIgnoreCondition);
7475

7576
/// <summary>
7677
/// Reads all records of the given query from the database, unpacking into a C# array of tuples in field order

src/ProgressOnderwijsUtils/Data/SqlBatch.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Buffers;
22
using System.Data.Common;
33
using System.Text.Json;
4+
using System.Text.Json.Serialization;
45

56
namespace ProgressOnderwijsUtils;
67

@@ -211,8 +212,15 @@ public readonly record struct JsonSqlCommand(ParameterizedSql Sql, CommandTimeou
211212
public JsonSqlCommand WithTimeout(CommandTimeout timeout)
212213
=> this with { CommandTimeout = timeout, };
213214

214-
public void Execute(SqlConnection conn, IBufferWriter<byte> buffer, JsonWriterOptions options)
215+
public void Execute(SqlConnection conn, IBufferWriter<byte> buffer, JsonWriterOptions options, JsonIgnoreCondition defaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)
215216
{
217+
if (defaultIgnoreCondition is JsonIgnoreCondition.Always) {
218+
throw new ArgumentException("The value cannot be 'Always'", nameof(defaultIgnoreCondition));
219+
}
220+
if (defaultIgnoreCondition is JsonIgnoreCondition.WhenWritingDefault) {
221+
throw new NotSupportedException($"defaultIgnoreCondition {JsonIgnoreCondition.WhenWritingDefault} is not supported");
222+
}
223+
216224
using var cmd = this.ReusableCommand(conn);
217225
var reader = ExecuteReader(cmd);
218226
using var disposeReader = reader;
@@ -225,8 +233,12 @@ public void Execute(SqlConnection conn, IBufferWriter<byte> buffer, JsonWriterOp
225233
while (Read(cmd, reader)) {
226234
writer.WriteStartObject();
227235
for (var i = 0; i < table.Length; i++) {
228-
if (!reader.IsDBNull(i)) {
229-
var name = table[i].ColumnName;
236+
var name = table[i].ColumnName;
237+
if (reader.IsDBNull(i)) {
238+
if (defaultIgnoreCondition is JsonIgnoreCondition.Never) {
239+
writer.WriteNull(name);
240+
}
241+
} else {
230242
var type = table[i].DataType;
231243
var sqlType = table[i].DataTypeName;
232244
if (type == typeof(bool)) {

src/ProgressOnderwijsUtils/ProgressOnderwijsUtils.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<Import Project="..\NugetPackagesCommon.props" />
33
<PropertyGroup Label="Configuration">
4-
<Version>110.0.0</Version>
5-
<PackageReleaseNotes>Update of NuGet packages.</PackageReleaseNotes>
4+
<Version>110.1.0</Version>
5+
<PackageReleaseNotes>Added standaard configuration parm for configuring the serialization of null-properties when reading JSON from SQL query.</PackageReleaseNotes>
66
<Title>ProgressOnderwijsUtils</Title>
77
<Description>Collection of utilities developed by ProgressOnderwijs</Description>
88
<PackageTags>ProgressOnderwijs</PackageTags>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[
2+
{
3+
"I": 1,
4+
"S": "een"
5+
},
6+
{
7+
"S": "twee"
8+
},
9+
{
10+
"I": 2
11+
},
12+
{}
13+
][
14+
{
15+
"I": 1,
16+
"S": "een"
17+
},
18+
{
19+
"I": null,
20+
"S": "twee"
21+
},
22+
{
23+
"I": 2,
24+
"S": null
25+
},
26+
{
27+
"I": null,
28+
"S": null
29+
}
30+
]

test/ProgressOnderwijsUtils.Tests/Data/ReadJsonTest.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.IO.Pipelines;
22
using System.Text.Json;
33
using System.Text.Json.Nodes;
4+
using System.Text.Json.Serialization;
45

56
namespace ProgressOnderwijsUtils.Tests.Data;
67

@@ -217,4 +218,35 @@ ReadJsonPocoTestId int not null
217218
}
218219
}
219220
}
221+
222+
[Fact]
223+
public void Null_properties_can_be_serialized_by_configuration()
224+
{
225+
SQL(
226+
$"""
227+
create table #ReadJsonNullsTest (
228+
I int null
229+
, S nvarchar(12) null
230+
);
231+
"""
232+
).ExecuteNonQuery(Connection);
233+
234+
SQL(
235+
$"""
236+
insert into #ReadJsonNullsTest (I, S) values
237+
(1, 'een')
238+
, (null, 'twee')
239+
, (2, null)
240+
, (null, null)
241+
"""
242+
).ExecuteNonQuery(Connection);
243+
244+
var pipe = new Pipe();
245+
SQL($"select t.* from #ReadJsonNullsTest t").ReadJson(Connection, pipe.Writer, new() { Indented = true, });
246+
SQL($"select t.* from #ReadJsonNullsTest t").ReadJson(Connection, pipe.Writer, new() { Indented = true, }, JsonIgnoreCondition.Never);
247+
pipe.Writer.Complete();
248+
249+
var json = Encoding.UTF8.GetString(pipe.Reader.ReadAsync().GetAwaiter().GetResult().Buffer);
250+
ApprovalTest.CreateHere().AssertUnchangedAndSave(json);
251+
}
220252
}

0 commit comments

Comments
 (0)