Kemal Tezer Dilsiz Kemal Tezer Dilsiz - 3 months ago 26
C# Question

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

Answer

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