Uploaded image for project: 'Entity Framework'
  1. Entity Framework
  2. EF-71

Mapping of ObjectIds to strings in entities

    • Type: Icon: New Feature New Feature
    • Resolution: Duplicate
    • Priority: Icon: Critical - P2 Critical - P2
    • 8.0.0
    • Affects Version/s: Public Preview 1

      When mapping MongoDB documents to C# classes, having string properties in the classes simplifies the handling of ObjectIds very much. In the existing driver for C#, this can be done by applying an [BsonRepresentation(BsonType.ObjectId)]-attribute to the property (also works if the property is an array or enumeration). However, this had no effect for the EF provider. 

      Also, adding a conversion when defining the model did not help, but led to an exception: 

      modelBuilder.Entity<Movie>()
        .ToCollection("movies")
        .Property(x => x.Id)
        .HasElementName("_id")
        .HasConversion(x => ObjectId.Parse, x => x.ToString());

      Exception: 
      System.FormatException: Cannot deserialize a 'String' from BsonType 'ObjectId'.
      at MongoDB.Bson.Serialization.Serializers.StringSerializer.DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
      at MongoDB.Bson.Serialization.Serializers.SealedClassSerializerBase`1.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
      at MongoDB.Bson.Serialization.Serializers.SerializerBase`1.MongoDB.Bson.Serialization.IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
      at MongoDB.Bson.Serialization.IBsonSerializerExtensions.Deserialize(IBsonSerializer serializer, BsonDeserializationContext context)
      at MongoDB.Bson.Serialization.BsonSerializationInfo.DeserializeValue(BsonValue value)
      at MongoDB.EntityFrameworkCore.Serializers.SerializationHelper.ReadElementValue[T](BsonDocument document, BsonSerializationInfo elementSerializationInfo)
      Using strings instead of an ObjectId type also simplifies the JSON serialization of the class. ObjectId objects are serialized like this by default: 

      { "timestamp": 1463423888, "machine": 15897363, "pid": -13653, "increment": 13451573, "creationTime": "2016-05-16T18:38:08Z" }

      This format is neither recognizable as an ObjectId by a human, nor can it be used as URL parameter in an API easily. So one would have to create a custom serializer for the API anyway; better yet if the EF provider supported the mapping in the same way as the existing driver for C#. 

      Additional side info: creating an EDM-model for OData based upon the class also had difficulties with the id  being an ObjectId; I expect this to handle a string without a problem.

      (sorry, I'm not a MongoDB employee so I had to create a bug issue for this. From my point of view, it's more of an improvement - but an important one)

            Assignee:
            Unassigned Unassigned
            Reporter:
            m.wildgruber@sevantage.de Markus Wildgruber
            Votes:
            4 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: