Testing MongoDb EntityFrameworkCore

I’m trying to use MongoDB.EntityFrameworkCore 7 preview.1. Should the BsonElement attribute work on an entity model? I have my Entity model designed with standard pascal case property names and I have an existing MongoDb collection. I’m getting an error on trying to query an item in the collection. “Element ‘Address’ not found.” If I change all my entity properties to lower case it works.

 [BsonElement("name")]
 public string Name { get; set; } = string.Empty;
 [BsonElement("address")]
 public PostalAddress Address { get; set; }

Does the BsonElement work in the 7.0.0-preview.1 version?

Hi, @Jay_Bowman,

Welcome to the MongoDB Community Forums and thank you for trying EFCore 7 preview.1. Preview 1 does not contain a convention to read BSON attributes, but we are considering adding this for release. At the moment, you can either match the casing of property names between your models and the database or you can override them using the model builder. For example, you can override DbContext.OnModelCreating in your derived DbContext class similar to the following:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        var customerModelBuilder = modelBuilder.Entity<Customer>();
        customerModelBuilder.ToCollection("customers");
        customerModelBuilder.Property(x => x.BillingAddress).HasElementName("billingAddress");
        customerModelBuilder.Property(x => x.FirstName).HasElementName("firstName");
        customerModelBuilder.Property(x => x.LastName).HasElementName("surName");
    }

Hope this helps.

Sincerely,
James

1 Like

Another quick point to note if you prefer attributes over the code-first model builder approach. You can use the EF-provided [Column("address"]. Although these are technically elements in the BSON document and not columns, EF likes to call things tables and columns due to its relational heritage. We do have a [Collection("collName")] synonym to [Table("tableName")] but we haven’t implemented the [Element("elemName")] equivalent. We may simply enable use of our BSON attributes such as [BsonElement("elemName")] in the next preview.

Hi James,

This is not working for me. I migrated a few Cosmos Containers to Mongo. I noticed Mongo turned all my Id properties to _id.

Now, when I try to fetch my records, I encounter the following error.

Executed MQL query
app-spaccurate-account-api-dev.Provider.aggregate([?])
[00:28:21 ERR] An exception occurred while iterating over the results of a query for context type 'Repository.MongoDB.DbContext.AccountMongoDbContext'.
System.InvalidOperationException: Document element is missing for required non-nullable property 'Id'.
   at MongoDB.EntityFrameworkCore.Storage.BsonBinding.GetPropertyValue[T](BsonDocument document, IReadOnlyProperty property)
   at lambda_method21(Closure, BsonDocument, Int32)
   at System.Linq.Enumerable.SelectIterator[TSource,TResult](IEnumerable`1 source, Func`3 selector)+MoveNext()
   at MongoDB.EntityFrameworkCore.Query.Visitors.ProjectionBindingRemovingExpressionVisitor.PopulateCollection[TEntity,TCollection](IClrCollectionAccessor accessor, IEnumerable`1 entities)
   at lambda_method18(Closure, QueryContext, BsonDocument)
   at MongoDB.EntityFrameworkCore.Query.QueryingEnumerable`2.Enumerator.MoveNextHelper()
   at MongoDB.EntityFrameworkCore.Query.QueryingEnumerable`2.Enumerator.MoveNextAsync()

Here is the line in my Configuration file:
builder.Property<Guid>(x => x.Id).HasElementName("_id")

I stepped into EF Core and reached the point where it creates the lambda expression, but it ignores the annotation, which is present as “Mongo:HasElementName” and the value is the GUID for that record.

My Mongo object _id is of type UUID (not an ObjectId). I am not sure what else to do here. I am stuck. I even changed my Id to _id (which is a horrible solution), and the message was the same except for the property type that recognized it as “Provider_id”

I see people setting attributes to their Domain Aggregates, but I don’t think that’s the correct solution. The Domain shouldn’t have any knowledge of the persistence layer.

What am I doing wrong here?

Thanks!

Hi Jose.

Did you get this working?

It’s not easy to tell what’s going on here. Do you have a small minimal repro I can try and step through?