Kemal Tezer Dilsiz
Kemal Tezer Dilsiz

Reputation: 4009

How to modify DbContext base constructor parameter as its being passed?

In this project I am trying to migrate from .NET to .NET Core. Here I have a code that I want to implement in .NET Core.

public partial class CompanyFormsContext : DbContext
{
    public CompanyFormsContext()
        : base("name=CompanyFormsContext")
    {
    }

    public CompanyFormsContext(string connName)
        : base("name=" + connName)
    {
    }
...
}

In .NET Core, string is not accepted as a parameter to DbContext. Instead, you can pass DbContextOptions as a parameter. For example, in the following link: http://ef.readthedocs.io/en/latest/miscellaneous/configuring-dbcontext.html

You can see the example:

public class BloggingContext : DbContext
{
    public BloggingContext(DbContextOptions<BloggingContext> options)
        : base(options)
    { }

    public DbSet<Blog> Blogs { get; set; }
}

and

var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlite("Filename=./blog.db");

using (var context = new BloggingContext(optionsBuilder.Options))
{
    // do stuff
}

what I want to do is similar to this. I could possibly create an instance of DbContextOptions and pass it but I do not know how I would modify the SqlServer connection as I am passing it through the base class constructor.

The most important thing that I cannot figure out is that I want to be able to keep my empty constructor which would trigger a default "CompanyFormsContext" connection. It would also be great if I could simply change the connection name while passing it as a parameter in the CompanyFormsContext constructors.

I was thinking of the following as an alternative way instead of the base constructors but I would prefer to keep the base constructor functionality.

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (connName == null)
        {
            optionsBuilder.UseSqlServer(@"Server=.\;Integrated Security=True;Database=CompanyFormsContext");
        }
        else
        {
            optionsBuilder.UseSqlServer(@"Server=.\;Integrated Security=True;Database=" + connName);
        }
    }

Upvotes: 3

Views: 4602

Answers (1)

Koopakiller
Koopakiller

Reputation: 2883

You could create a static method which returns a DbContextOptions<BloggingContext> which will be created from a passed connection string.

So your class could look something like this:

public partial class CompanyFormsContext : DbContext
{
    public CompanyFormsContext()
        : base(CreateOptions(null))
    {
    }

    public CompanyFormsContext(string connName)
        : base(CreateOptions(connName))
    {
    }

    private static DbContextOptions<BloggingContext> CreateOptions(string connName)
    {
        var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
        optionsBuilder.UseSqlite("Filename=./blog.db");
        if (connName == null)
        {
            optionsBuilder.UseSqlServer(@"Server=.\;Integrated Security=True;Database=CompanyFormsContext");
        }
        else
        {
            optionsBuilder.UseSqlServer(@"Server=.\;Integrated Security=True;Database=" + connName);
        }
        return optionsBuilder.Options;
    }

Upvotes: 3

Related Questions