Skip to content

Commit 9bb6557

Browse files
committed
Merge branch 'main' into efcore-dotnet-10
2 parents d8132d5 + 9c14613 commit 9bb6557

File tree

65 files changed

+2645
-530
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2645
-530
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,4 @@
44
# For syntax help see:
55
# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax
66

7-
# The @googleapis/api-spanner is the default owner for changes in this repo
8-
* @googleapis/api-spanner
7+
* @googleapis/spanner-team @googleapis/cloud-sdk-dotnet-team

.github/workflows/ado-net-tests.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
- name: Install Go
2424
uses: actions/setup-go@v6
2525
with:
26-
go-version: '1.25.x'
26+
go-version: '1.26.x'
2727
- name: Checkout go-sql-spanner
2828
uses: actions/checkout@v6
2929
with:
@@ -45,9 +45,10 @@ jobs:
4545
working-directory: spanner-ado-net/spanner-ado-net-samples-tests
4646
run: dotnet test --verbosity normal
4747
shell: bash
48+
if: matrix.os != 'ubuntu-24.04-arm'
4849
- name: dotnet run sample
4950
working-directory: spanner-ado-net/spanner-ado-net-samples
5051
run: dotnet run HelloWorld
5152
shell: bash
5253
# Docker is only supported on Linux on GitHub Actions
53-
if: runner.os == 'Linux'
54+
if: runner.os == 'Linux' && matrix.os != 'ubuntu-24.04-arm'

.github/workflows/build-and-test.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ on:
99

1010
jobs:
1111
unit-tests:
12-
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
os: [ubuntu-latest, macos-latest, windows-latest]
15+
runs-on: ${{ matrix.os }}
1316
steps:
1417
- uses: actions/checkout@v6
1518
- name: Setup .NET

.github/workflows/samples.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ jobs:
2121
- name: Run samples
2222
working-directory: ./Google.Cloud.EntityFrameworkCore.Spanner.Samples
2323
run: dotnet run All
24+
- name: Compile sample model
25+
working-directory: ./Google.Cloud.EntityFrameworkCore.Spanner.Samples
26+
run: |
27+
dotnet tool install --global dotnet-ef
28+
dotnet tool restore
29+
./optimize.sh

.github/workflows/sync-spannerlib-code.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ jobs:
2525
shell: bash
2626

2727
- name: Create Pull Request
28-
uses: peter-evans/create-pull-request@v6
28+
uses: peter-evans/create-pull-request@v8
2929
with:
3030
token: ${{ secrets.GITHUB_TOKEN }}
3131
commit-message: "chore: sync SpannerLib code"
3232
branch: automated-spanner-lib-code-update
3333
title: "chore: sync SpannerLib code"
3434
body: "Update the ADO.NET driver with the latest SpannerLib code."
3535
base: main
36+
committer: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>

.release-please-manifest.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
".": "3.8.0"
2+
".": "3.10.0",
3+
"spanner-ado-net/spanner-ado-net": "0.2.3"
34
}

Google.Cloud.EntityFrameworkCore.Spanner.IntegrationTests/Google.Cloud.EntityFrameworkCore.Spanner.IntegrationTests.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
<PrivateAssets>all</PrivateAssets>
2525
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2626
</PackageReference>
27-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
27+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.3.0" />
2828
<PackageReference Include="Moq" Version="4.20.72" />
2929
<PackageReference Include="xunit" Version="2.9.3" />
3030
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
31-
<PackageReference Include="coverlet.collector" Version="6.0.4" />
31+
<PackageReference Include="coverlet.collector" Version="8.0.0" />
3232
<PackageReference Include="Xunit.SkippableFact" Version="1.5.61" />
3333
</ItemGroup>
3434

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System.Text.Json.Serialization;
16+
17+
namespace Google.Cloud.EntityFrameworkCore.Spanner.IntegrationTests.Model;
18+
19+
/// <summary>
20+
/// JSON type with property names containing special characters that require bracket notation
21+
/// in JSON path expressions. This is used to test that VisitJsonScalar correctly handles
22+
/// property names containing dots, spaces, quotes, and backslashes.
23+
/// </summary>
24+
public class JsonPropertiesWithSpecialNames
25+
{
26+
/// <summary>
27+
/// Property with a dot in the JSON name - requires bracket notation $["property.with.dot"]
28+
/// </summary>
29+
[JsonPropertyName("property.with.dot")]
30+
public string PropertyWithDot { get; set; }
31+
32+
/// <summary>
33+
/// Property with a space in the JSON name - requires bracket notation $["property with space"]
34+
/// </summary>
35+
[JsonPropertyName("property with space")]
36+
public string PropertyWithSpace { get; set; }
37+
38+
/// <summary>
39+
/// Property with a single quote in the JSON name - requires bracket notation and quote escaping $["it's"]
40+
/// </summary>
41+
[JsonPropertyName("it's")]
42+
public string PropertyWithSingleQuote { get; set; }
43+
44+
/// <summary>
45+
/// Property with double quotes in the JSON name - requires bracket notation and escaping $["say \"hello\""]
46+
/// </summary>
47+
[JsonPropertyName("say \"hello\"")]
48+
public string PropertyWithDoubleQuote { get; set; }
49+
50+
/// <summary>
51+
/// Normal property without special characters - uses dot notation $.NormalProperty
52+
/// </summary>
53+
public string NormalProperty { get; set; }
54+
}

Google.Cloud.EntityFrameworkCore.Spanner.IntegrationTests/Model/Receipt.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Google.Cloud.EntityFrameworkCore.Spanner.IntegrationTests.Model;
44

5-
public struct Receipt
5+
public class Receipt
66
{
77
public DateOnly Date { get; set; }
88

Google.Cloud.EntityFrameworkCore.Spanner.IntegrationTests/Model/SpannerSampleDbContext.cs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public SpannerSampleDbContext(DbContextOptions<SpannerSampleDbContext> options)
3838
public virtual DbSet<Tracks> Tracks { get; set; }
3939
public virtual DbSet<Venues> Venues { get; set; }
4040
public virtual DbSet<TicketSales> TicketSales { get; set; }
41+
public virtual DbSet<TestEntityWithSpecialJsonProperties> TestEntityWithSpecialJsonProperties { get; set; }
4142

4243
protected override void OnModelCreating(ModelBuilder modelBuilder)
4344
{
@@ -218,11 +219,29 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
218219

219220
modelBuilder.Entity<TicketSales>(entity =>
220221
{
221-
entity.Property(e => e.Receipt)
222-
.HasConversion<string>(
223-
v => v == null ? null : JsonConvert.SerializeObject(v),
224-
v => v == null ? null : JsonConvert.DeserializeObject<Receipt>(v))
225-
.HasColumnType("JSON");
222+
// Use EF Core 8+ JSON column support with owned entities
223+
// This allows EF Core to generate JsonScalarExpression nodes for property access
224+
// which our VisitJsonScalar implementation translates to JSON_VALUE calls
225+
entity.OwnsOne(e => e.Receipt, ownedBuilder =>
226+
{
227+
ownedBuilder.ToJson();
228+
ownedBuilder.Property(r => r.Date).IsRequired();
229+
ownedBuilder.Property(r => r.Number).IsRequired();
230+
});
231+
});
232+
233+
modelBuilder.Entity<TestEntityWithSpecialJsonProperties>(entity =>
234+
{
235+
entity.HasKey(e => e.Id);
236+
entity.Property(e => e.Id).ValueGeneratedNever();
237+
238+
// Use EF Core 8+ JSON column support with owned entity
239+
// The JsonPropertiesWithSpecialNames class has properties with [JsonPropertyName]
240+
// attributes that contain special characters (dots, spaces, quotes)
241+
entity.OwnsOne(e => e.JsonData, ownedBuilder =>
242+
{
243+
ownedBuilder.ToJson();
244+
});
226245
});
227246
}
228247
}

0 commit comments

Comments
 (0)