Skip to content

Commit

Permalink
Fixed MongoDB query support. (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
mgernand authored Jun 12, 2024
1 parent 0dd3d05 commit 522ad53
Show file tree
Hide file tree
Showing 15 changed files with 108 additions and 82 deletions.
2 changes: 1 addition & 1 deletion GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
next-version: 8.2.0
next-version: 8.3.0
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,20 @@ public static void UseStronglyTypedId(this EntityTypeBuilder entityTypeBuilder)

foreach(PropertyInfo property in properties)
{
Type idType = property.PropertyType;
Type valueType = idType.GetStronglyTypedIdValueType();
Type originalMemberType = property.PropertyType;
Type memberType = Nullable.GetUnderlyingType(originalMemberType) ?? originalMemberType;

Type converterTypeTemplate = typeof(StronglyTypedIdConverter<,>);
Type converterType = converterTypeTemplate.MakeGenericType(idType, valueType);
if(memberType.IsStronglyTypedId())
{
Type valueType = memberType.GetStronglyTypedIdValueType();

entityTypeBuilder
.Property(property.Name)
.HasConversion(converterType);
Type converterTypeTemplate = typeof(StronglyTypedIdConverter<,>);
Type converterType = converterTypeTemplate.MakeGenericType(memberType, valueType);

entityTypeBuilder
.Property(property.Name)
.HasConversion(converterType);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[PublicAPI]
public sealed class StronglyTypedIdConverter<TStronglyTypedId, TValue> : ValueConverter<TStronglyTypedId, TValue>
where TStronglyTypedId : StronglyTypedId<TStronglyTypedId, TValue>
where TValue : IComparable
where TValue : IComparable, IComparable<TValue>, IEquatable<TValue>
{
/// <summary>
/// Initializes a new instance of the <see cref="StronglyTypedIdConverter{TStronglyTypedId,TValue}" /> type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public JsonContract ResolveContract(Type type)
/// <inheritdoc />
public IEnumerator<IContractResolver> GetEnumerator()
{
// ReSharper disable once NotDisposedResourceIsReturned
return this.contractResolvers.GetEnumerator();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[PublicAPI]
public sealed class StronglyTypedIdConverter<TStronglyTypedId, TValue> : JsonConverter<TStronglyTypedId>
where TStronglyTypedId : StronglyTypedId<TStronglyTypedId, TValue>
where TValue : IComparable
where TValue : IComparable, IComparable<TValue>, IEquatable<TValue>
{
/// <inheritdoc />
public override bool CanWrite => true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static Func<object, BsonValue> Serialize(Type stronglyTypedIdType)
}

/// <summary>
/// Deserialize a ID instance from the given bson value.
/// Deserialize an ID instance from the given bson value.
/// </summary>
/// <param name="stronglyTypedIdType"></param>
/// <returns></returns>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
[PublicAPI]
public sealed class StronglyTypedIdSerializer<TStronglyTypedId, TValue> : SerializerBase<TStronglyTypedId>
where TStronglyTypedId : StronglyTypedId<TStronglyTypedId, TValue>
where TValue : IComparable
where TValue : IComparable, IComparable<TValue>, IEquatable<TValue>
{
private readonly IBsonSerializer idValueSerializer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Fluxera.StronglyTypedId.SystemTextJson
[PublicAPI]
public sealed class StronglyTypedIdConverter<TStronglyTypedId, TValue> : JsonConverter<TStronglyTypedId>
where TStronglyTypedId : StronglyTypedId<TStronglyTypedId, TValue>
where TValue : IComparable
where TValue : IComparable, IComparable<TValue>, IEquatable<TValue>
{
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, TStronglyTypedId value, JsonSerializerOptions options)
Expand Down
3 changes: 2 additions & 1 deletion src/Fluxera.StronglyTypedId/Guard.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
namespace Fluxera.StronglyTypedId
// ReSharper disable PossibleInvalidOperationException
namespace Fluxera.StronglyTypedId
{
using JetBrains.Annotations;
using System;
Expand Down
20 changes: 0 additions & 20 deletions src/Fluxera.StronglyTypedId/IStronglyTypedId.cs

This file was deleted.

44 changes: 22 additions & 22 deletions src/Fluxera.StronglyTypedId/StronglyTypedId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
/// <typeparam name="TValue">The type of the IDs value.</typeparam>
[PublicAPI]
[TypeConverter(typeof(StronglyTypedIdConverter))]
public abstract class StronglyTypedId<TStronglyTypedId, TValue> : IStronglyTypedId<TStronglyTypedId, TValue>
public abstract class StronglyTypedId<TStronglyTypedId, TValue> : IComparable<TStronglyTypedId>, IEquatable<TStronglyTypedId>
where TStronglyTypedId : StronglyTypedId<TStronglyTypedId, TValue>
where TValue : notnull, IComparable
where TValue : IComparable, IComparable<TValue>, IEquatable<TValue>
{
/// <summary>
/// To ensure hashcode uniqueness, a carefully selected random number multiplier
Expand Down Expand Up @@ -139,6 +139,25 @@ public bool Equals(TStronglyTypedId other)
return this.Equals(other as object);
}

/// <inheritdoc />
public sealed override bool Equals(object obj)
{
if(obj is null)
{
return false;
}

if(object.ReferenceEquals(this, obj))
{
return true;
}

StronglyTypedId<TStronglyTypedId, TValue> other = obj as StronglyTypedId<TStronglyTypedId, TValue>;
return other != null
&& this.GetType() == other.GetType()
&& this.GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());
}

/// <inheritdoc />
public int CompareTo(TStronglyTypedId other)
{
Expand Down Expand Up @@ -190,25 +209,6 @@ public static explicit operator StronglyTypedId<TStronglyTypedId, TValue>(TValue
return Create(value);
}

/// <inheritdoc />
public sealed override bool Equals(object obj)
{
if(obj is null)
{
return false;
}

if(object.ReferenceEquals(this, obj))
{
return true;
}

StronglyTypedId<TStronglyTypedId, TValue> other = obj as StronglyTypedId<TStronglyTypedId, TValue>;
return other != null
&& this.GetType() == other.GetType()
&& this.GetEqualityComponents().SequenceEqual(other.GetEqualityComponents());
}

/// <inheritdoc />
public sealed override int GetHashCode()
{
Expand Down Expand Up @@ -238,7 +238,7 @@ public sealed override string ToString()
}

/// <summary>
/// Gets all components of the value object that are used for equality. <br />
/// Gets all components of the strongly-typed ID that are used for equality. <br />
/// The default implementation get all properties via reflection. One
/// can at any time override this behavior with a manual or custom implementation.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Fluxera.StronglyTypedId/StronglyTypedIdConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private static TypeConverter CreateActualConverter(Type stronglyTypedIdType)

internal sealed class StronglyTypedIdConverter<TStronglyTypedId, TValue> : TypeConverter
where TStronglyTypedId : StronglyTypedId<TStronglyTypedId, TValue>
where TValue : notnull, IComparable
where TValue : IComparable, IComparable<TValue>, IEquatable<TValue>
{
// ReSharper disable once StaticMemberInGenericType
private static TypeConverter IdValueConverter { get; } = GetIdValueConverter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ public class QueryTests
private TestDbContext context;
#pragma warning restore NUnit1032

[SetUp]
[OneTimeSetUp]
public void SetUp()
{
this.context = DbContextFactory.Generate();
}

[TearDown]
[OneTimeTearDown]
public void TearDown()
{
this.context?.Dispose();
}

[Test]
public async Task ShouldFindByPrimitiveValueObject()
public async Task ShouldFindByStronglyTypedId()
{
Person linqFilterResult = await this.context
.Set<Person>()
Expand All @@ -36,5 +36,17 @@ public async Task ShouldFindByPrimitiveValueObject()

linqFilterResult.Should().NotBeNull();
}

[Ignore("Fix this later")]
[Test]
public async Task ShouldFindByValue()
{
Person linqFilterResult = await this.context
.Set<Person>()
.Where(x => x.Id == "12345")
.FirstOrDefaultAsync();

linqFilterResult.Should().NotBeNull();
}
}
}
40 changes: 26 additions & 14 deletions tests/Fluxera.StronglyTypedId.LiteDB.UnitTests/QueryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,27 @@
public class QueryTests
{
private LiteDatabaseAsync database;
private ILiteCollectionAsync<Person> collection;

[SetUp]
public void SetUp()
[OneTimeSetUp]
public async Task SetUp()
{
BsonMapper.Global.Entity<Person>().Id(x => x.Id);
BsonMapper.Global.UseStronglyTypedId();

this.database = new LiteDatabaseAsync($"{Guid.NewGuid():N}.db");
this.collection = this.database.GetCollection<Person>();

Person person = new Person
{
Id = PersonId.Create("fcd5f4f9753a4284a2d0f500b9b23cf8"),
Name = "Tester"
};

await this.collection.InsertAsync(person);
}

[TearDown]
[OneTimeTearDown]
public void TearDown()
{
this.database?.Dispose();
Expand All @@ -34,20 +44,22 @@ public void TearDown()
[Test]
public async Task ShouldFindByStronglyTypedID()
{
ILiteCollectionAsync<Person> collection = this.database.GetCollection<Person>();

Person person = new Person
{
Id = PersonId.Create(Guid.NewGuid().ToString("N")),
Name = "Tester"
};

await collection.InsertAsync(person);

Person linqFilterResult = await collection
.AsQueryable()
.Where(x => x.Id == person.Id)
.Where(x => x.Id == PersonId.Create("fcd5f4f9753a4284a2d0f500b9b23cf8"))
.FirstOrDefaultAsync();
linqFilterResult.Should().NotBeNull();
}

[Ignore("Fix this later")]
[Test]
public async Task ShouldFindByValue()
{
Person linqFilterResult = await this.collection
.AsQueryable()
.Where(x => x.Id == "6669b52802357c9886f6d24f")
.FirstOrDefaultAsync();

linqFilterResult.Should().NotBeNull();
}
}
Expand Down
31 changes: 23 additions & 8 deletions tests/Fluxera.StronglyTypedId.MongoDB.UnitTests/QueryTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
namespace Fluxera.StronglyTypedId.MongoDB.UnitTests
{
using System;
using System.Threading.Tasks;
using FluentAssertions;
using Fluxera.StronglyTypedId.MongoDB.UnitTests.Model;
using global::MongoDB.Bson;
using global::MongoDB.Bson.Serialization.Conventions;
using global::MongoDB.Driver;
using global::MongoDB.Driver.Linq;
Expand All @@ -13,30 +11,47 @@
[TestFixture]
public class QueryTests
{
[Test]
public async Task ShouldFindByStronglyTypedID()
private IMongoCollection<Person> collection;

[OneTimeSetUp]
public async Task SetUp()
{
ConventionPack pack = [];
pack.UseStronglyTypedId();
ConventionRegistry.Register("ConventionPack", pack, t => true);

IMongoClient client = new MongoClient(GlobalFixture.ConnectionString);
IMongoDatabase database = client.GetDatabase(GlobalFixture.Database);
IMongoCollection<Person> collection = database.GetCollection<Person>("People");
this.collection = database.GetCollection<Person>("People");

Person person = new Person
{
Id = PersonId.Create(ObjectId.GenerateNewId().ToString()),
Id = PersonId.Create("6669b52802357c9886f6d24f"),
Name = "Tester"
};

await collection.InsertOneAsync(person);
}

Person linqFilterResult = await collection
[Test]
public async Task ShouldFindByStronglyTypedID()
{
Person linqFilterResult = await this.collection
.AsQueryable()
.Where(x => x.Id == person.Id)
.Where(x => x.Id == PersonId.Create("6669b52802357c9886f6d24f"))
.FirstOrDefaultAsync();
linqFilterResult.Should().NotBeNull();
}

[Test]
public async Task ShouldFindByValue()
{
Person linqFilterResult = await this.collection
.AsQueryable()
.Where(x => x.Id == "6669b52802357c9886f6d24f")
.FirstOrDefaultAsync();

linqFilterResult.Should().NotBeNull();
}
}
}

0 comments on commit 522ad53

Please sign in to comment.