MongoFramework
MongoFramework copied to clipboard
Set CollectionName
How do I set the CollectionName? I have several MongoDbSet<> properties on my dbContext that use the same Type. I would expect it to take the property name but it appears to be using the type name.
I think it's related to https://github.com/TurnerSoftware/MongoFramework/issues/249 since it's putting everything into a single collection. Is it possible to make it use the the property name on the db set as the default collection name with an optional attribute that can override it?
While you can control the collection name, it is tightly coupled to the type. Internally, types are matched 1-to-1 against an EntityDefinition
- this is how the mapping system works.
To try and achieve the effect you want, your best bet would be to have an abstract type with the shared properties and have each of the properties with a custom type that extends it. This is similar to the behaviour with Entity Framework (or at least was the last time I used it).
Like this?
public class TypeThatGoesIntoMongoDbSetA : TypeUsedInMultipleDbSets
{
}
public class TypeThatGoesIntoMongoDbSetB : TypeUsedInMultipleDbSets
{
}
public class MyDbContext : MongoDbContext
{
public MyDbContext (IMongoDbConnection connection) : base(connection) { }
public MongoDbSet<TypeThatGoesIntoMongoDbSetA> CollectionA { get; set; }
public MongoDbSet<TypeThatGoesIntoMongoDbSetB> CollectionB { get; set; }
}
Yeah - that way you have multiple distinct collections with the same properties.
I know it is cumbersome but due to the type-nature of the internal entity definition, this is likely the best option for what you want specifically.
Ok thanks, I had an Upsert method that will also require overloads so things will get cumbersome..
EF allows you to modify the table name the dbcontext level.
void OnModelCreating (DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyType>().ToTable("t_MyCustomTypeName");
}
An attribute on the MongoDbSet property or even better an option to reflect the actual dbset property name as these will always be unique per context would also be an elegant way to achieve this. I am not sure if EF has this or whether the long term goal of this project is to build an exact replica of EF.
Would this be impossible to achieve with MongoFramework? Other than this after 2 days usage I find it is a really nice abstraction.
A lot of the models I use across various projects are generated from a schema which often have the same root entity. I am reluctant to decorate these with attributes as they get regenerated during a build so having a feature to control this outside the type would be really great.
EF allows you to change this at the dbcontext level.
void OnModelCreating (DbModelBuilder modelBuilder) { modelBuilder.Entity<MyType>().ToTable("t_MyCustomTypeName"); }
Would this be impossible to achieve with MongoFramework? Other than this after 2 days usage I find it is a really nice abstraction.
This is one of the types of things I want to add support for later - being able to modify the entity definition (the type I use internally for things) within the MongoDbContext
. It isn't there today and I don't have a specific timeframe for it but it is definitely a feature I want to add.
That said, even if this functionality exists today, everything is still tied to the type - that is to say, an entity definition that contains what properties are mapped, what indexes there are and the collection name will always be tied to a type. At various points of the code, the entity definition is looked up by the type and it has to be that way.
An attribute on the MongoDbSet property or even better an option to reflect the actual dbset property name as these will always be unique per context would also be an elegant way to achieve this.
If/when I add something like OnModelCreating
, you'll be able to easily specify whatever collection name you want including doing something like below to set the collection to the property:
public class MyDbContext : MongoDbContext
{
public MyDbContext (IMongoDbConnection connection) : base(connection) { }
public MongoDbSet<TypeThatGoesIntoMongoDbSetA> CollectionA { get; set; }
public MongoDbSet<TypeThatGoesIntoMongoDbSetB> CollectionB { get; set; }
protected void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TypeThatGoesIntoMongoDbSetA>()
.ToCollection(nameof(CollectionA));
}
}
In terms of automatically mapping property names to entity definitions, I probably won't do that. Partially because it would involve changing how a lot of things work underneath and partially because it just feels kinda weird to me. That doesn't mean I won't change my mind in the future but for now, the best path forward for having collection names mapped to properties is when I have OnModelCreating
-like support.
I am not sure if EF has this or whether the long term goal of this project is to build an exact replica of EF.
Honestly I'm mainly aiming for the feel of EF and take a lot of cues from them. In terms of matching functionality, I mainly plan to match the parts that make sense but I won't sacrifice MongoDB-isms for complete compatibility with EF.
A lot of the models I use across various projects are generated from a schema which often have the same root entity. I am reluctant to decorate these with attributes as they get regenerated during a build so having a feature to control this outside the type would be really great.
Look, I totally understand that use case - being able to specify the entity definition by means other than modifying the type is definitely something I want to cater to.
I didn't mention this first because it isn't something I'd want to push users towards normally as they'd need to deal with some other problems (like potential race conditions) but there is a way you can modify the entity definition outside of modifying the type.
The EntityMapping
class does expose methods to retrieve the underlying entity definition.
As an additional caveat if you do pursue this - this class sits within the core "infrastructure" of MongoFramework and I'm more likely to make breaking changes on this (and other classes within this name space). All of the context/dbset stuff is pretty concrete and is unlikely to have a breaking change in comparison.
With #336 being completed, you can do exactly what you described with a mapping builder for MongoFramework. There is a basic example on there readme here: https://github.com/TurnerSoftware/MongoFramework#entity-mapping-basics