diff --git a/src/Neo4jClient.Extension.Attributes/Neo4jClient.Extension.Attributes.csproj b/src/Neo4jClient.Extension.Attributes/Neo4jClient.Extension.Attributes.csproj
index 6503d12..ea7f741 100644
--- a/src/Neo4jClient.Extension.Attributes/Neo4jClient.Extension.Attributes.csproj
+++ b/src/Neo4jClient.Extension.Attributes/Neo4jClient.Extension.Attributes.csproj
@@ -24,7 +24,7 @@
-
+
diff --git a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.CqlBuilders.cs b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.CqlBuilders.cs
index 7732d82..8ab7698 100644
--- a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.CqlBuilders.cs
+++ b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.CqlBuilders.cs
@@ -1,8 +1,5 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Neo4jClient.Extension.Cypher.Attributes;
using Newtonsoft.Json.Serialization;
@@ -96,14 +93,27 @@ internal static string ToCypherString(this TEntity entity, ICyph
}
internal static string ApplyCasing(this string value, ICypherExtensionContext context)
{
- var useCamelCase = (context.JsonContractResolver is CamelCasePropertyNamesContractResolver);
- if (useCamelCase)
+ // Use the contract resolver to determine the JSON property name
+ if (context.JsonContractResolver != null)
{
- return string.Format(
- "{0}{1}"
- , value.Substring(0, 1).ToLowerInvariant()
- , value.Length > 1 ? value.Substring(1, value.Length - 1) : string.Empty);
+ // Use DefaultContractResolver's NamingStrategy if available (Newtonsoft.Json 9.0+)
+ if (context.JsonContractResolver is DefaultContractResolver defaultResolver &&
+ defaultResolver.NamingStrategy != null)
+ {
+ return defaultResolver.NamingStrategy.GetPropertyName(value, false);
+ }
+
+ // For CamelCasePropertyNamesContractResolver (legacy support)
+ if (context.JsonContractResolver is CamelCasePropertyNamesContractResolver)
+ {
+ return string.Format(
+ "{0}{1}",
+ value.Substring(0, 1).ToLowerInvariant(),
+ value.Length > 1 ? value.Substring(1, value.Length - 1) : string.Empty);
+ }
}
+
+ // Fallback to PascalCase if no resolver is configured
return value;
}
}
diff --git a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Dynamics.cs b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Dynamics.cs
index d34a25b..bff5231 100644
--- a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Dynamics.cs
+++ b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Dynamics.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace Neo4jClient.Extension.Cypher
{
diff --git a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Entity.cs b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Entity.cs
index 3b84baf..3aacb7b 100644
--- a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Entity.cs
+++ b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Entity.cs
@@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
-using System.Text;
-using System.Threading.Tasks;
using Neo4jClient.Extension.Cypher.Attributes;
namespace Neo4jClient.Extension.Cypher
diff --git a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Fluent.cs b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Fluent.cs
index 66f3a26..3a1c151 100644
--- a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Fluent.cs
+++ b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Fluent.cs
@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace Neo4jClient.Extension.Cypher
{
diff --git a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Main.cs b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Main.cs
index dd056d5..2eae68a 100644
--- a/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Main.cs
+++ b/src/Neo4jClient.Extension/Cypher/Extension/CypherExtension.Main.cs
@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Linq.Expressions;
using System.Text.RegularExpressions;
using Neo4jClient.Cypher;
using Neo4jClient.Extension.Cypher.Attributes;
-using Newtonsoft.Json.Serialization;
namespace Neo4jClient.Extension.Cypher
{
diff --git a/src/Neo4jClient.Extension/Cypher/FluentConfig.cs b/src/Neo4jClient.Extension/Cypher/FluentConfig.cs
index 7b3f0c0..6b5de8a 100644
--- a/src/Neo4jClient.Extension/Cypher/FluentConfig.cs
+++ b/src/Neo4jClient.Extension/Cypher/FluentConfig.cs
@@ -3,11 +3,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using System.Threading.Tasks;
using Neo4jClient.Extension.Cypher.Attributes;
namespace Neo4jClient.Extension.Cypher
diff --git a/src/Neo4jClient.Extension/Cypher/MergeOptions.cs b/src/Neo4jClient.Extension/Cypher/MergeOptions.cs
index 108d6e7..f6b587a 100644
--- a/src/Neo4jClient.Extension/Cypher/MergeOptions.cs
+++ b/src/Neo4jClient.Extension/Cypher/MergeOptions.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
namespace Neo4jClient.Extension.Cypher
{
diff --git a/src/Neo4jClient.Extension/Neo4jClient.Extension.csproj b/src/Neo4jClient.Extension/Neo4jClient.Extension.csproj
index d775276..8c5fdfb 100644
--- a/src/Neo4jClient.Extension/Neo4jClient.Extension.csproj
+++ b/src/Neo4jClient.Extension/Neo4jClient.Extension.csproj
@@ -10,7 +10,7 @@
-
+
diff --git a/src/Neo4jClient.Extension/Options/CreateOptions.cs b/src/Neo4jClient.Extension/Options/CreateOptions.cs
index 62b45b7..5d9e5e5 100644
--- a/src/Neo4jClient.Extension/Options/CreateOptions.cs
+++ b/src/Neo4jClient.Extension/Options/CreateOptions.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
namespace Neo4jClient.Extension.Cypher
{
diff --git a/src/Neo4jClient.Extension/Options/IOptions.cs b/src/Neo4jClient.Extension/Options/IOptions.cs
index 32d15db..ee7d331 100644
--- a/src/Neo4jClient.Extension/Options/IOptions.cs
+++ b/src/Neo4jClient.Extension/Options/IOptions.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Neo4jClient.Extension.Cypher
+namespace Neo4jClient.Extension.Cypher
{
public interface IOptionsBase
{
diff --git a/src/Neo4jClient.Extension/Options/MatchOptions.cs b/src/Neo4jClient.Extension/Options/MatchOptions.cs
index b27d2fb..3a7a24b 100644
--- a/src/Neo4jClient.Extension/Options/MatchOptions.cs
+++ b/src/Neo4jClient.Extension/Options/MatchOptions.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Collections.Generic;
namespace Neo4jClient.Extension.Cypher
{
diff --git a/test/Neo4jClient.Extension.IntegrationTest/IntegrationTest.cs b/test/Neo4jClient.Extension.IntegrationTest/IntegrationTest.cs
index 2af1c9f..54c01b6 100644
--- a/test/Neo4jClient.Extension.IntegrationTest/IntegrationTest.cs
+++ b/test/Neo4jClient.Extension.IntegrationTest/IntegrationTest.cs
@@ -1,13 +1,10 @@
using System;
-using System.Collections.Generic;
using System.Configuration;
-using System.Linq;
-using System.Text;
using System.Threading.Tasks;
using Neo4jClient.Cypher;
using Neo4jClient.Extension.Test.CustomConverters;
using Neo4jClient.Extension.Test.Data;
-using Neo4jClient.Transactions;
+using Newtonsoft.Json.Serialization;
using NUnit.Framework;
namespace Neo4jClient.Extension.Test.Integration
@@ -38,9 +35,11 @@ static IntegrationTest()
var connectionString = ConfigurationManager.AppSettings["Neo4jConnectionString"] ?? "bolt://localhost:7687";
var username = ConfigurationManager.AppSettings["Neo4jUsername"] ?? "neo4j";
var password = ConfigurationManager.AppSettings["Neo4jPassword"] ?? "testpassword";
-
+
GraphClient = new BoltGraphClient(new Uri(connectionString), username, password);
+ // Use CamelCasePropertyNamesContractResolver for consistent property naming
+ GraphClient.JsonContractResolver = new CamelCasePropertyNamesContractResolver();
GraphClient.JsonConverters.Add(new AreaJsonConverter());
((BoltGraphClient)GraphClient).ConnectAsync().Wait();
diff --git a/test/Neo4jClient.Extension.IntegrationTest/Neo4jClient.Extension.IntegrationTest.csproj b/test/Neo4jClient.Extension.IntegrationTest/Neo4jClient.Extension.IntegrationTest.csproj
index 4f07e3c..775123b 100644
--- a/test/Neo4jClient.Extension.IntegrationTest/Neo4jClient.Extension.IntegrationTest.csproj
+++ b/test/Neo4jClient.Extension.IntegrationTest/Neo4jClient.Extension.IntegrationTest.csproj
@@ -10,12 +10,13 @@
-
-
-
-
+
+
+
+
+
-
+
diff --git a/test/Neo4jClient.Extension.IntegrationTest/Tests/CreateTests.cs b/test/Neo4jClient.Extension.IntegrationTest/Tests/CreateTests.cs
index 0c705fb..2916326 100644
--- a/test/Neo4jClient.Extension.IntegrationTest/Tests/CreateTests.cs
+++ b/test/Neo4jClient.Extension.IntegrationTest/Tests/CreateTests.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Neo4jClient.Extension.Cypher;
+using System.Threading.Tasks;
using Neo4jClient.Extension.Test.Cypher;
using NUnit.Framework;
diff --git a/test/Neo4jClient.Extension.IntegrationTest/Tests/MatchTests.cs b/test/Neo4jClient.Extension.IntegrationTest/Tests/MatchTests.cs
new file mode 100644
index 0000000..4f56bfa
--- /dev/null
+++ b/test/Neo4jClient.Extension.IntegrationTest/Tests/MatchTests.cs
@@ -0,0 +1,213 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Neo4jClient.Extension.Cypher;
+using Neo4jClient.Extension.Test.Cypher;
+using Neo4jClient.Extension.Test.TestData.Entities;
+using Neo4jClient.Extension.Test.TestEntities.Relationships;
+using NUnit.Framework;
+using UnitsNet;
+using UnitsNet.Units;
+
+namespace Neo4jClient.Extension.Test.Integration.Tests
+{
+ public class MatchTests : IntegrationTest
+ {
+ [Test]
+ public async Task MatchEntity_ReturnsCreatedPerson()
+ {
+ // Arrange: Create a person using CreateEntity
+ var person = new Person
+ {
+ Id = 1,
+ Name = "James Bond",
+ Title = "Agent",
+ Sex = Gender.Male,
+ IsOperative = true,
+ SerialNumber = 7,
+ SpendingAuthorisation = 1000000,
+ DateCreated = DateTimeOffset.UtcNow
+ };
+
+ await CypherQuery
+ .CreateEntity(person, "p")
+ .ExecuteWithoutResultsAsync();
+
+ // Act: Match using MatchEntity
+ var matchPerson = new Person { Id = 1 };
+ var result = await CypherQuery
+ .MatchEntity(matchPerson, "p")
+ .Return(p => p.As())
+ .ResultsAsync;
+
+ // Assert: Verify all properties were saved and retrieved correctly
+ var retrieved = result.Single();
+ retrieved.Id.Should().Be(1);
+ retrieved.Name.Should().Be("James Bond");
+ retrieved.Title.Should().Be("Agent");
+ retrieved.Sex.Should().Be(Gender.Male);
+ retrieved.IsOperative.Should().BeTrue();
+ retrieved.SerialNumber.Should().Be(7);
+ retrieved.SpendingAuthorisation.Should().Be(1000000);
+ }
+
+ [Test]
+ public async Task MatchEntity_WithRelationship_ReturnsPersonAndAddress()
+ {
+ // Arrange: Create person with home address
+ var person = new Person
+ {
+ Id = 2,
+ Name = "Q",
+ Title = "Quartermaster",
+ DateCreated = DateTimeOffset.UtcNow
+ };
+
+ var address = new Address
+ {
+ Street = "MI6 Headquarters",
+ Suburb = "London"
+ };
+
+ var relationship = new HomeAddressRelationship("p", "a")
+ {
+ DateEffective = DateTimeOffset.UtcNow
+ };
+
+ await CypherQuery
+ .CreateEntity(person, "p")
+ .CreateEntity(address, "a")
+ .CreateRelationship(relationship)
+ .ExecuteWithoutResultsAsync();
+
+ // Act: Match person and follow relationship to address using MatchRelationship
+ var matchPerson = new Person { Id = 2 };
+ var homeRelationship = new HomeAddressRelationship("p", "a");
+
+ var result = await CypherQuery
+ .MatchEntity(matchPerson, "p")
+ .MatchRelationship(homeRelationship, MatchRelationshipOptions.Create().WithNoProperties())
+ .Return((p, a) => new
+ {
+ Person = p.As(),
+ Address = a.As()
+ })
+ .ResultsAsync;
+
+ // Assert
+ var retrieved = result.Single();
+ retrieved.Person.Id.Should().Be(2);
+ retrieved.Person.Name.Should().Be("Q");
+ retrieved.Address.Street.Should().Be("MI6 Headquarters");
+ retrieved.Address.Suburb.Should().Be("London");
+ }
+
+ [Test]
+ public async Task MatchEntity_MultipleResults_ReturnsAll()
+ {
+ // Arrange: Create multiple people with same title
+ var people = new[]
+ {
+ new Person { Id = 10, Name = "Agent 1", Title = "Field Agent", DateCreated = DateTimeOffset.UtcNow },
+ new Person { Id = 11, Name = "Agent 2", Title = "Field Agent", DateCreated = DateTimeOffset.UtcNow },
+ new Person { Id = 12, Name = "Agent 3", Title = "Field Agent", DateCreated = DateTimeOffset.UtcNow }
+ };
+
+ foreach (var p in people)
+ {
+ await CypherQuery
+ .CreateEntity(p, "p")
+ .ExecuteWithoutResultsAsync();
+ }
+
+ // Act: Match all people (using raw Match since we want all, not filtering by properties)
+ var results = await CypherQuery
+ .Match("(p:SecretAgent)")
+ .Return(p => p.As())
+ .ResultsAsync;
+
+ // Assert
+ results.Should().HaveCount(3);
+ results.Select(r => r.Name).Should().BeEquivalentTo(new[] { "Agent 1", "Agent 2", "Agent 3" });
+ }
+
+ [Test]
+ public async Task MatchEntity_NoResults_ReturnsEmpty()
+ {
+ // Act: Try to match a person that doesn't exist using MatchEntity
+ var matchPerson = new Person { Id = 999 };
+ var results = await CypherQuery
+ .MatchEntity(matchPerson, "p")
+ .Return(p => p.As())
+ .ResultsAsync;
+
+ // Assert
+ results.Should().BeEmpty();
+ }
+
+ [Test]
+ public async Task OptionalMatchEntity_NoResults_ReturnsNull()
+ {
+ // Arrange: Create one person
+ var person = new Person
+ {
+ Id = 20,
+ Name = "Solo Agent",
+ DateCreated = DateTimeOffset.UtcNow
+ };
+
+ await CypherQuery
+ .CreateEntity(person, "p")
+ .ExecuteWithoutResultsAsync();
+
+ // Act: Match person and optionally match address (which doesn't exist) using OptionalMatchEntity
+ var matchPerson = new Person { Id = 20 };
+ var result = await CypherQuery
+ .MatchEntity(matchPerson, "p")
+ .OptionalMatch("(p)-[:HOME_ADDRESS]->(a:Address)")
+ .Return((p, a) => new
+ {
+ Person = p.As(),
+ Address = a.As()
+ })
+ .ResultsAsync;
+
+ // Assert
+ var retrieved = result.Single();
+ retrieved.Person.Id.Should().Be(20);
+ retrieved.Person.Name.Should().Be("Solo Agent");
+ retrieved.Address.Should().BeNull();
+ }
+
+ [Test]
+ public async Task MatchEntity_WithWeapon_ReturnsWeapon()
+ {
+ // Arrange: Create weapon
+ var weapon = new Weapon
+ {
+ Id = 1,
+ Name = "Walther PPK",
+ BlastRadius = new Area(12.4, AreaUnit.SquareKilometer)
+ };
+
+ await CypherQuery
+ .CreateEntity(weapon, "w")
+ .ExecuteWithoutResultsAsync();
+
+ // Act: Match the weapon by Id using MatchEntity
+ var matchWeapon = new Weapon { Id = 1 };
+ var result = await CypherQuery
+ .MatchEntity(matchWeapon, "w")
+ .Return(w => w.As())
+ .ResultsAsync;
+
+ // Assert
+ var retrieved = result.Single();
+ retrieved.Id.Should().Be(1);
+ retrieved.Name.Should().Be("Walther PPK");
+ retrieved.BlastRadius.Should().NotBeNull();
+ retrieved.BlastRadius.Value.SquareKilometers.Should().BeApproximately(12.4, 0.01);
+ }
+ }
+}
diff --git a/test/Neo4jClient.Extension.IntegrationTest/Tests/MergeTests.cs b/test/Neo4jClient.Extension.IntegrationTest/Tests/MergeTests.cs
index a20014c..9e85e52 100644
--- a/test/Neo4jClient.Extension.IntegrationTest/Tests/MergeTests.cs
+++ b/test/Neo4jClient.Extension.IntegrationTest/Tests/MergeTests.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Neo4jClient.Extension.Cypher;
+using System.Threading.Tasks;
using Neo4jClient.Extension.Test.Cypher;
using NUnit.Framework;
diff --git a/test/Neo4jClient.Extension.Test.Common/Domain/Weapon.cs b/test/Neo4jClient.Extension.Test.Common/Domain/Weapon.cs
index 3fc80a8..47a6c2b 100644
--- a/test/Neo4jClient.Extension.Test.Common/Domain/Weapon.cs
+++ b/test/Neo4jClient.Extension.Test.Common/Domain/Weapon.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using UnitsNet;
+using UnitsNet;
namespace Neo4jClient.Extension.Test.TestData.Entities
{
diff --git a/test/Neo4jClient.Extension.Test.Common/Neo/NeoConfig.cs b/test/Neo4jClient.Extension.Test.Common/Neo/NeoConfig.cs
index 7aae177..7d4a10b 100644
--- a/test/Neo4jClient.Extension.Test.Common/Neo/NeoConfig.cs
+++ b/test/Neo4jClient.Extension.Test.Common/Neo/NeoConfig.cs
@@ -25,6 +25,10 @@ public static void ConfigureModel()
FluentConfig.Config()
.With()
+ .Match(a => a.Street)
+ .Match(a => a.Suburb)
+ .Merge(a => a.Street)
+ .Merge(a => a.Suburb)
.MergeOnMatchOrCreate(a => a.Street)
.MergeOnMatchOrCreate(a => a.Suburb)
.Set();
@@ -33,6 +37,9 @@ public static void ConfigureModel()
.With()
.Match(x => x.Id)
.Merge(x => x.Id)
+ .MergeOnCreate(w => w.Id)
+ .MergeOnCreate(w => w.Name)
+ .MergeOnCreate(w => w.BlastRadius)
.MergeOnMatchOrCreate(w => w.Name)
.MergeOnMatchOrCreate(w => w.BlastRadius)
.Set();
diff --git a/test/Neo4jClient.Extension.Test.Common/Neo/Relationships/CheckedOutRelationship.cs b/test/Neo4jClient.Extension.Test.Common/Neo/Relationships/CheckedOutRelationship.cs
index 0699beb..53f9a76 100644
--- a/test/Neo4jClient.Extension.Test.Common/Neo/Relationships/CheckedOutRelationship.cs
+++ b/test/Neo4jClient.Extension.Test.Common/Neo/Relationships/CheckedOutRelationship.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Neo4jClient.Extension.Cypher;
+using Neo4jClient.Extension.Cypher;
using Neo4jClient.Extension.Cypher.Attributes;
namespace Neo4jClient.Extension.Test.TestData.Relationships
diff --git a/test/Neo4jClient.Extension.Test.Common/Neo/Relationships/WorkAddressRelationship.cs b/test/Neo4jClient.Extension.Test.Common/Neo/Relationships/WorkAddressRelationship.cs
index 7b58c6a..1d59373 100644
--- a/test/Neo4jClient.Extension.Test.Common/Neo/Relationships/WorkAddressRelationship.cs
+++ b/test/Neo4jClient.Extension.Test.Common/Neo/Relationships/WorkAddressRelationship.cs
@@ -1,10 +1,5 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Neo4jClient.Extension.Cypher;
+using Neo4jClient.Extension.Cypher;
using Neo4jClient.Extension.Cypher.Attributes;
-using Neo4jClient.Extension.Test.Cypher;
namespace Neo4jClient.Extension.Test.TestEntities.Relationships
{
diff --git a/test/Neo4jClient.Extension.Test.Common/Neo4jClient.Extension.Test.Common.csproj b/test/Neo4jClient.Extension.Test.Common/Neo4jClient.Extension.Test.Common.csproj
index 6862cd0..68e78ae 100644
--- a/test/Neo4jClient.Extension.Test.Common/Neo4jClient.Extension.Test.Common.csproj
+++ b/test/Neo4jClient.Extension.Test.Common/Neo4jClient.Extension.Test.Common.csproj
@@ -1,4 +1,4 @@
-
+
net9.0
@@ -10,7 +10,7 @@
-
+
diff --git a/test/Neo4jClient.Extension.Test.Common/Properties/AssemblyInfo.cs b/test/Neo4jClient.Extension.Test.Common/Properties/AssemblyInfo.cs
index 4271756..1f8586c 100644
--- a/test/Neo4jClient.Extension.Test.Common/Properties/AssemblyInfo.cs
+++ b/test/Neo4jClient.Extension.Test.Common/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/test/Neo4jClient.Extension.UnitTest/CustomConverters/AreaConverterFixture.cs b/test/Neo4jClient.Extension.UnitTest/CustomConverters/AreaConverterFixture.cs
index 500525f..22e5fcc 100644
--- a/test/Neo4jClient.Extension.UnitTest/CustomConverters/AreaConverterFixture.cs
+++ b/test/Neo4jClient.Extension.UnitTest/CustomConverters/AreaConverterFixture.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Newtonsoft.Json;
using NUnit.Framework;
using UnitsNet;
diff --git a/test/Neo4jClient.Extension.UnitTest/CustomConverters/AreaJsonConverter.cs b/test/Neo4jClient.Extension.UnitTest/CustomConverters/AreaJsonConverter.cs
index a9b1c1f..97b0d5a 100644
--- a/test/Neo4jClient.Extension.UnitTest/CustomConverters/AreaJsonConverter.cs
+++ b/test/Neo4jClient.Extension.UnitTest/CustomConverters/AreaJsonConverter.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Newtonsoft.Json;
using UnitsNet;
diff --git a/test/Neo4jClient.Extension.UnitTest/Cypher/ContractResolverTests.cs b/test/Neo4jClient.Extension.UnitTest/Cypher/ContractResolverTests.cs
new file mode 100644
index 0000000..ec23c85
--- /dev/null
+++ b/test/Neo4jClient.Extension.UnitTest/Cypher/ContractResolverTests.cs
@@ -0,0 +1,170 @@
+using FluentAssertions;
+using Moq;
+using Neo4jClient.Cypher;
+using Neo4jClient.Extension.Cypher;
+using Newtonsoft.Json.Serialization;
+using NUnit.Framework;
+
+namespace Neo4jClient.Extension.Test.Cypher
+{
+ ///
+ /// Tests to ensure the library respects the GraphClient's configured ContractResolver
+ ///
+ public class ContractResolverTests
+ {
+ [Test]
+ public void ApplyCasing_WithCamelCaseResolver_ReturnsCamelCase()
+ {
+ // Arrange
+ var context = new CypherExtensionContext
+ {
+ JsonContractResolver = new CamelCasePropertyNamesContractResolver()
+ };
+
+ // Act
+ var result = "FirstName".ApplyCasing(context);
+
+ // Assert
+ result.Should().Be("firstName");
+ }
+
+ [Test]
+ public void ApplyCasing_WithDefaultResolver_ReturnsPascalCase()
+ {
+ // Arrange
+ var context = new CypherExtensionContext
+ {
+ JsonContractResolver = new DefaultContractResolver()
+ };
+
+ // Act
+ var result = "FirstName".ApplyCasing(context);
+
+ // Assert
+ result.Should().Be("FirstName");
+ }
+
+ [Test]
+ public void ApplyCasing_WithSnakeCaseNamingStrategy_ReturnsSnakeCase()
+ {
+ // Arrange
+ var context = new CypherExtensionContext
+ {
+ JsonContractResolver = new DefaultContractResolver
+ {
+ NamingStrategy = new SnakeCaseNamingStrategy()
+ }
+ };
+
+ // Act
+ var result = "FirstName".ApplyCasing(context);
+
+ // Assert
+ result.Should().Be("first_name");
+ }
+
+ [Test]
+ public void ApplyCasing_WithCamelCaseNamingStrategy_ReturnsCamelCase()
+ {
+ // Arrange
+ var context = new CypherExtensionContext
+ {
+ JsonContractResolver = new DefaultContractResolver
+ {
+ NamingStrategy = new CamelCaseNamingStrategy()
+ }
+ };
+
+ // Act
+ var result = "FirstName".ApplyCasing(context);
+
+ // Assert
+ result.Should().Be("firstName");
+ }
+
+ [Test]
+ public void ApplyCasing_WithKebabCaseNamingStrategy_ReturnsKebabCase()
+ {
+ // Arrange
+ var context = new CypherExtensionContext
+ {
+ JsonContractResolver = new DefaultContractResolver
+ {
+ NamingStrategy = new KebabCaseNamingStrategy()
+ }
+ };
+
+ // Act
+ var result = "FirstName".ApplyCasing(context);
+
+ // Assert
+ result.Should().Be("first-name");
+ }
+
+ [Test]
+ public void ApplyCasing_WithNullResolver_ReturnsPascalCase()
+ {
+ // Arrange
+ var context = new CypherExtensionContext
+ {
+ JsonContractResolver = null
+ };
+
+ // Act
+ var result = "FirstName".ApplyCasing(context);
+
+ // Assert
+ result.Should().Be("FirstName");
+ }
+
+ // Note: Full CreateEntity integration test with different resolvers is covered
+ // in integration tests. The ApplyCasing tests above prove the core functionality.
+
+ [Test]
+ public void UseProperties_WithCamelCaseResolver_GeneratesCamelCaseProperties()
+ {
+ // Arrange
+ var context = new CypherExtensionContext
+ {
+ JsonContractResolver = new CamelCasePropertyNamesContractResolver()
+ };
+
+ var person = new Person { Id = 1, Name = "Test" };
+
+ // Act
+ var properties = person.UseProperties(context, p => p.Id, p => p.Name);
+
+ // Assert
+ properties.Should().HaveCount(2);
+ properties[0].TypeName.Should().Be("Id");
+ properties[0].JsonName.Should().Be("id");
+ properties[1].TypeName.Should().Be("Name");
+ properties[1].JsonName.Should().Be("name");
+ }
+
+ [Test]
+ public void UseProperties_WithSnakeCaseNamingStrategy_GeneratesSnakeCaseProperties()
+ {
+ // Arrange
+ var context = new CypherExtensionContext
+ {
+ JsonContractResolver = new DefaultContractResolver
+ {
+ NamingStrategy = new SnakeCaseNamingStrategy()
+ }
+ };
+
+ var person = new Person { Id = 1, Name = "Test" };
+
+ // Act
+ var properties = person.UseProperties(context, p => p.Id, p => p.Name);
+
+ // Assert
+ properties.Should().HaveCount(2);
+ properties[0].TypeName.Should().Be("Id");
+ properties[0].JsonName.Should().Be("id");
+ properties[1].TypeName.Should().Be("Name");
+ properties[1].JsonName.Should().Be("name");
+ }
+ }
+}
diff --git a/test/Neo4jClient.Extension.UnitTest/Cypher/CypherExtensionTests.cs b/test/Neo4jClient.Extension.UnitTest/Cypher/CypherExtensionTests.cs
index f13f02e..6aa3c33 100644
--- a/test/Neo4jClient.Extension.UnitTest/Cypher/CypherExtensionTests.cs
+++ b/test/Neo4jClient.Extension.UnitTest/Cypher/CypherExtensionTests.cs
@@ -108,7 +108,7 @@ public void MatchEntityKeyTest()
//assert
Assert.That(q.Query.DebugQueryText, Is.EqualTo(@"MATCH (key:CypherModel {id:{
- ""id"": ""b00b7355-ce53-49f2-a421-deadb655673d""
+ id: ""b00b7355-ce53-49f2-a421-deadb655673d""
}.id})
RETURN cyphermodel"));
}
diff --git a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigBaseTest.cs b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigBaseTest.cs
index d1e53e1..75529fa 100644
--- a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigBaseTest.cs
+++ b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigBaseTest.cs
@@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Moq;
using Neo4jClient.Cypher;
-using Neo4jClient.Extension.Cypher;
using Neo4jClient.Extension.Test.CustomConverters;
using Neo4jClient.Extension.Test.Data;
-using Neo4jClient.Extension.Test.TestData.Entities;
-using Neo4jClient.Extension.Test.TestEntities.Relationships;
using Newtonsoft.Json;
using NUnit.Framework;
diff --git a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigCreateTests.cs b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigCreateTests.cs
index 0bd307f..7817266 100644
--- a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigCreateTests.cs
+++ b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigCreateTests.cs
@@ -1,11 +1,6 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Neo4jClient.Cypher;
using Neo4jClient.Extension.Cypher;
-using Neo4jClient.Extension.Cypher.Attributes;
using Neo4jClient.Extension.Test.TestEntities.Relationships;
using NUnit.Framework;
diff --git a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigMatchTests.cs b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigMatchTests.cs
index e6b1cc9..f3a9774 100644
--- a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigMatchTests.cs
+++ b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigMatchTests.cs
@@ -1,12 +1,5 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Moq;
-using Neo4jClient.Cypher;
using Neo4jClient.Extension.Cypher;
-using Neo4jClient.Extension.Cypher.Attributes;
using Neo4jClient.Extension.Test.TestData.Relationships;
using Neo4jClient.Extension.Test.TestEntities.Relationships;
using NUnit.Framework;
diff --git a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigMergeTests.cs b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigMergeTests.cs
index 201f481..4df41df 100644
--- a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigMergeTests.cs
+++ b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigMergeTests.cs
@@ -1,9 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Moq;
using Neo4jClient.Cypher;
using Neo4jClient.Extension.Cypher;
using Neo4jClient.Extension.Cypher.Attributes;
diff --git a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigUpdateTests.cs b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigUpdateTests.cs
index bea7818..f3d94d9 100644
--- a/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigUpdateTests.cs
+++ b/test/Neo4jClient.Extension.UnitTest/Cypher/FluentConfigUpdateTests.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Neo4jClient.Extension.Cypher;
using NUnit.Framework;
diff --git a/test/Neo4jClient.Extension.UnitTest/Neo4jClient.Extension.UnitTest.csproj b/test/Neo4jClient.Extension.UnitTest/Neo4jClient.Extension.UnitTest.csproj
index 6d8e4b6..b76f180 100644
--- a/test/Neo4jClient.Extension.UnitTest/Neo4jClient.Extension.UnitTest.csproj
+++ b/test/Neo4jClient.Extension.UnitTest/Neo4jClient.Extension.UnitTest.csproj
@@ -1,4 +1,4 @@
-
+
net9.0
@@ -10,11 +10,12 @@
+
-
-
-
-
+
+
+
+