Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BsonType configuration #97

Merged
merged 2 commits into from
May 31, 2024
Merged

BsonType configuration #97

merged 2 commits into from
May 31, 2024

Conversation

damieng
Copy link
Member

@damieng damieng commented May 23, 2024

Provides a HasBsonType fluent API that allows the model builder to configure specific properties to be stored as specific BSON types.

Fixes EF-127

A subsequent PR will further expose this feature out so that BsonRepresentation attributes can be recognized (EF-44)

@damieng damieng requested a review from a team as a code owner May 23, 2024 13:11
Copy link
Collaborator

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HasBsonType looks good but the unrelated work should be moved into their own PRs.

@@ -53,65 +54,127 @@ public static class MongoPropertyBuilderExtensions
=> (PropertyBuilder<TProperty>)HasElementName((PropertyBuilder)propertyBuilder, name);

/// <summary>
/// Configures the <see cref="DateTimeKind"/> for the property.
/// Configures the document element that the property is mapped to when targeting MongoDB.
/// If an empty string is supplied then the property will not be persisted.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although not recommended, an empty string is a valid field name in MongoDB. null however is not a valid field name. Is an empty string not mapping a property an EF convention or something that we are introducing?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was just improving the documentation. EF uses this convention in other providers. If we want to support writing to an element with an empty name we may be able to that but we'd need to create a new ticket and figure out an alternative marker for unmapped properties.

propertyBuilder.Metadata.SetDateTimeKind(dateTimeKind);
if (!CanSetElementName(propertyBuilder, name, fromDataAnnotation))
{
return null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we not be throwing an InvalidOperationException in this case? If we return null, then we will throw a NullReferenceException when we chain the fluent API.

Copy link
Member Author

@damieng damieng May 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This return null pattern is used across all EF providers. You can see it in the Cosmos, SqlServer and relational base providers.

{
propertyBuilder.Metadata.SetDateTimeKind(dateTimeKind);
ArgumentNullException.ThrowIfNull(bsonType);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BsonType is an enum and cannot be null.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to make this BsonType? so that null is valid and can be used to unset a previous HasBsonType configuration?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, let's do that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now done.


// Mongo structs
_ when type == typeof(ObjectId) => ObjectIdSerializer.Instance,
_ when type == typeof(Decimal128) => new Decimal128Serializer(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should configure serializers for ObjectId and Decimal128, but this seems unrelated to the PR at hand. Move to a separate PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't add/remove any support, it just groups them together with comments as the list was getting long. I can revert.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this clean-up from the PR.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems related to adding support for ObjectIdSerializer, not HasBsonType support.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new class for testing round-tripping data back and forth to MongoDB with an extra check via the C# driver. It came out of writing all the new BsonType tests as they were getting repetitive. It's not related to any other work.

{
var bsonDateTime = new BsonDateTime(dateTime);
return dateTime.Kind == DateTimeKind.Utc ? bsonDateTime.ToUniversalTime() : bsonDateTime.ToLocalTime();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to HasBsonType support. Move to separate PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is test-only code and relates to testing DateTime's which I need for the new BsonType tests that touch BsonDateTime.

I had a ToExpectedPrecision method I was previously using for some other BsonDateTime related tests but it didn't handle UTC. The new method is used for both the new tests and the old.

@damieng damieng requested a review from JamesKovacs May 27, 2024 19:17
Copy link
Collaborator

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@damieng damieng merged commit e185930 into mongodb:main May 31, 2024
34 checks passed
@damieng damieng deleted the ef-127 branch May 31, 2024 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants