Cyassin
Cyassin

Reputation: 1500

Entity Framework Core DbContextOptionsBuilder.UseModel creates EntityTypes that have no properties

I am working on a .NET Core project using entity framework core (2.0.1).

I have a plugin architecture requiring different models to be loaded based on the plugins attached, so trying to dynamically load the models when adding the dbcontext to the DI container using the DbContextOptionsBuilder.UseModel method.

Regardless on if I define a new Model or a ModelBuilder, the EntityTypes I am adding do not appear to be doing so correctly and once added to the dbcontext do not appear to have any properties.

I am not sure if there is a convention I need to be adding for this to work, or what I may be missing. Any help would be appreciated.

_services.AddDbContext<DataContext>(options =>
        {
            switch (_config.DatabaseType.ToLower())
            {
                case "postgres":
                    options.UseNpgsql(_config.ConnectionString);
                    break;
                case "sqlserver":
                    options.UseSqlServer(_config.ConnectionString);
                    break;
            }

            var convention = new Microsoft.EntityFrameworkCore.Metadata.Conventions.ConventionSet();
            var mb = new ModelBuilder(convention);
            foreach (var definition in definitionList)
            {
                mb.Entity(definition.Type);
            }
            options.UseModel(mb.Model);
        });

Resolves into:

enter image description here

Correctly creates the 5 EntityTypes, but then once I expand one of the Entity Types it has no properties.

enter image description here

If I do the same using the standard convention of adding the EntityType via the override of the dbcontext onmodelbuilding, the properties are all there correctly...

Upvotes: 0

Views: 4319

Answers (1)

poke
poke

Reputation: 388273

Yes, there are a few conventions by default, one of which is a PropertyDiscoveryConvention which sounds like it would make sure that all properties are added by default, but also other likely important ones like a KeyDiscoveryConvention, and lots of conventions that take care of identifying the mapping attributes.

You could probably ensure that you create the right conventions but it may be easier to move your logic into the database context instead. That way you can build on top of all the standard conventions, like one would normally do, and you won’t need to take care of that yourself. So maybe something like this:

class MyContext : DbContext
{
    private readonly IDbContextConfigurator _dbContextConfigurator;
    public MyContext(DbOptions<MyContext> dbOptions, IDbContextConfigurator dbContextConfigurator)
        : base(dbOptions)
    {
        _dbContextConfigurator = dbContextConfigurator;
    }


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

        _dbContextConfigurator.Configure(modelBuilder);
    }
}

So inside that IDbContextConfigurator you could then retrieve your configuration and configure your model directly on the model builder.

Upvotes: 1

Related Questions