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

Set CollectionName #250

Closed
grounzero opened this issue Aug 17, 2021 · 7 comments
Closed

Set CollectionName #250

grounzero opened this issue Aug 17, 2021 · 7 comments
Labels

Comments

@grounzero
Copy link

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.

@grounzero
Copy link
Author

I think it's related to #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?

@Turnerj
Copy link
Member

Turnerj commented Aug 17, 2021

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).

@grounzero
Copy link
Author

grounzero commented Aug 17, 2021

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; }

    }

@Turnerj
Copy link
Member

Turnerj commented Aug 17, 2021

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.

@grounzero
Copy link
Author

grounzero commented Aug 18, 2021

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.

@Turnerj
Copy link
Member

Turnerj commented Aug 18, 2021

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.

@Turnerj
Copy link
Member

Turnerj commented Jun 4, 2023

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

@Turnerj Turnerj closed this as completed Jun 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants