12

I'm trying to use EF Core tools to manage an SqlServer database I'm designing in a C# class library. It's in a class library because I need to use the database schema in both an MVC6 website and some command line tools.

I had to convert the class library to being a netapp because the current version of the tooling doesn't support class libraries, but I don't think that's the source of my problem.

My DbContext class looks like this:

public class ConnellDbContext : IdentityDbContext<ConnellUser>
{
    public ConnellDbContext( DbContextOptions<ConnellDbContext> options )
    {
    }

    // core tables
    public DbSet<Ballot> Ballots { get; set; }
    public DbSet<Campaign> Campaigns { get; set; }
    //...
}

When I run "dotnet ef migrations list" on the Package Manager Console, I get the following error message:

No parameterless constructor was found on 'ConnellDbContext'. Either add a parameterless constructor to 'ConnellDbContext' or add an implementation of 'IDbContextFactory' in the same assembly as 'ConnellDbContext'.

I'm not quite sure how to resolve this. It's easy enough to insert a parameterless constructor, but when I do I get the following error:

No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.

I >>think<< this means the console commands are not picking up the connection string information in my appsettings.json file:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-ConnellCampaigns;Trusted_Connection=True;MultipleActiveResultSets=true;AttachDbFilename=e:\\SqlServer\\Data\\ConnellCampaigns.mdf;"
  }
}

I'm missing something about how the EF tooling accesses the source code to do its magic. Any pointers or leads would be much appreciated.

Additional Info

Thanx to Mr. Anderson I've made a bit of progress. I added a parameterless constructor and overrode the OnConfiguring() method in my DbContext class:

protected override void OnConfiguring( DbContextOptionsBuilder optionsBuilder )
{
    var builder = new ConfigurationBuilder()
        .AddJsonFile( "appsettings.json", optional: true, reloadOnChange: true );

    IConfigurationRoot config = builder.Build();

    optionsBuilder.UseSqlServer(config.GetConnectionString("DefaultConnection") );
}

That didn't work, but explicitly including the actual connection string in the call to UseSqlServer() did. Thoughts on why the call based on "DefaultConnection" didn't work?

4
  • There is no such magic. EF employs the singleton model, with a static instance of DbContext<T> for every T. In order to create the instance, however, it needs parameterless ctor. Commented Aug 6, 2016 at 21:14
  • But then why is it gacking when I add such a ctor? Commented Aug 6, 2016 at 22:21
  • 1
    It looks like EF does not know which db connection to bind your context to. Did you try overriding OnConfiguring() in ConnellDbContext? Commented Aug 6, 2016 at 22:28
  • No, I didn't try that. The docs I read, to the extent I understood them, seemed to say that providing either a parameterless ctor or overriding OnConfiguring() would work. The former seemed easier. But I don't think I've got the parameterless ctor set up correctly (it's just an empty method at this point). Commented Aug 6, 2016 at 23:11

1 Answer 1

-1
public class ConnellDbContext : IdentityDbContext<ConnellUser>
{
    internal static string connection_string
    {
        get
        {
            return System.Configuration.ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
        }
    }

    public ConnellDbContext() : base(connection_string)
    {

    }
    // core tables
    public DbSet<Ballot> Ballots { get; set; }
    public DbSet<Campaign> Campaigns { get; set; }
    //...
}
Sign up to request clarification or add additional context in comments.

7 Comments

And where does connection_string come from?
@JohnyL you can create property which reads the connection string from the config. let me edit my answer for the same.
@JohnyL makes sense now?
First, this is EF Core - the connection string must be used in OnConfiguring method. Second, forgetting the first point, how will you pass connection string? Your ConnellDbContext's constructor does not receive connection string - it has nothing to pass to base.
honestly if this is EF Core I wouldn't have any mention of conn strings anywhere, no OnConfiguring either. everything will be injected in via DI (including conn details)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.