Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable the default constructor on a Database-First workflow

How can I prevent the use of the parameterless constructor of the generated DbContext?

var dcx = new DataEntities();

The default constructor is generated by the T4 template, and I thus cannot override it in a partial class. I would prefer it not compile, but a runtime error would also be good.

like image 845
Zev Spitz Avatar asked Jul 28 '14 09:07

Zev Spitz


3 Answers

You can modify the template to provide the constructor you want.

  • Open the *.Context.tt file
  • Go to line ~59
  • Change this code.

    public <#=code.Escape(container)#>()
        : base("name=<#=container.Name#>")
    
  • Into the default constructor you want, for example.

    public <#=code.Escape(container)#>(string nameOrConnectionString)
        : base(nameOrConnectionString)
    
  • Save

like image 143
Yuliam Chandra Avatar answered Sep 23 '22 06:09

Yuliam Chandra


You can inherit the DbContext created by the template, define your own constructor, and use the inherited DbContext instead of the one generated by the template.

public class MyModifiedDbContext : TheTemplateGeneratedDbContext
{
   public MyModifiedDbContext() 
   {
       // define your own constructor
   }
}

Or make it private to avoid its use, so you get the error at compile time

public class MyModifiedDbContext : TheTemplateGeneratedDbContext
{
   private MyModifiedDbContext() 
   // ...
}

Use MyModifiedDbContext instead of TheTemplateGeneratedDbContext

like image 21
JotaBe Avatar answered Sep 23 '22 06:09

JotaBe


I gave up waiting for EF Core team to add this as an option. I don't want to make and maintain my own T4 templates for this - that's nuts!

Solution for me was just to run some regex on the generated code as part of a powershell script.

fix-dbcontext.ps1

$filename=$args[0]

# load context file
$content = (Get-Content -Raw $filename) 

[regex] $commentOutConstructorRegex = '(?ms)(?<=: DbContext\s*.*?)(public.*?)(?=\s*public)'
$content = $commentOutConstructorRegex.Replace($content, '// Default constructor removed', 1)

[regex] $removeOnConfiguringRegex = '(?ms)(protected override void OnConfiguring).*?(?=\s*protected)'
$content = $removeOnConfiguringRegex.Replace($content, '// Generated OnConfiguring removed', 1)

[regex] $dateCommentRegex = '(?ms)(?=\s*public partial class)'
$content = $dateCommentRegex.Replace($content, "`r`n`t// Generated " + (Get-Date).ToString() + "`r`n", 1)

$content | Out-File -Encoding UTF8 $filename

This will:

  1. Remove the default constructor
  2. Remove the OnConfiguring method including hardcoded connection string
  3. Add the date in a comment

Just run it with .\fix-dbcontext.ps1 .\MyDBContext.cs.

You probably want to change that last line to context.txt instead of $filename until you're sure it does what you want.

IMPORTANT: This was tested only on EFCore templates, but if you understand my Regexes you should be able to modify it for EntityFramework if it doesn't already work.

like image 28
Simon_Weaver Avatar answered Sep 25 '22 06:09

Simon_Weaver