Closed Perlkonig closed 5 years ago
{{{on-model-creating}}}
just adds the entire method that is generated by EF Core scaffolding.
I think the easiest way to deal with this scenario is for you to create a partial DbContext
derived class, then include the OnModelCreating
override there and do whatever you need to do.
If, however, you want to generate the code for this method, then extend HbsCSharpDbContextGenerator
in a NET Standard 2.0 class library and override GenerateOnModelCreating
. You would then need to register your class in ScaffoldingDesignTimeServices.ConfigureDesignTimeServices
. Then you'll have full control -- although this approach requires more effort. :)
Thanks for your help! So if I understand what you're saying, I should create a non-scaffolded partial DbContext
class that inherits from the scaffolded one. And in that derived class's OnModelCreating
function, call the base
one that was scaffolded and then just drop my date handling code in after that. I don't know why I didn't think of that before. Thanks so much!
Actually partial classes do not involve inheritance. The two .cs files are just one class, so the class name needs to be the same in both files and include the partial keyword. See http://www.tutorialsteacher.com/csharp/csharp-partial-class
But in this case there will be two OnModelCreating
functions, no? The one scaffolding creates and the one that adds the date handing? I assumed that wasn't permissible.
I inherited for now and it works, but if there's a better way, I want to learn it! I'm still new to the ways of .NET. Thanks again.
Why don’t you remove the {{on-model-creating}} from the template and only have it in your custom partial class?
If you can do that, you don’t need to inherit. You can instead use partial classes.
Don't I need the one the scaffolding created? It's quite extensive. I'm trying to set things up so if I make a change to the database I can regenerate the entire schema with zero manual intervention. I'm in a database-first situation.
OK so then you should use a partial method that is called from the generated OnModelCreating method and implemented in your partial class. See the article I referenced earlier. That is the proper way to accomplish what you want to do.
Of course for that we would need to modify code generated for OnModelCreating. So in the meantime your workaround should suffice.
Many thanks.
I had the same requirement for extending OnModelCreating.
I ended up replacing the last three lines of the generated DbContext class with the following:
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
As suggested here: https://github.com/ErikEJ/EFCorePowerTools/issues/20
I'm currently doing this with a powershell script which gets run after the scaffolding, but it would be great if these lines could be added to the GenerateOnModelCreating method here:
In case it helps anyone in the meantime, here's my hacky powershell code:
$files = Get-ChildItem -Path $projectDir -Filter *Context.cs
foreach ($item in $files)
{
$search = Get-content $item.FullName
# strip last 3 lines
$search = $search[0..($search.count - 4)]
# add some new lines of our making!
$search += ""
$search += " OnModelCreatingPartial(modelBuilder);"
$search += " }"
$search += ""
$search += " partial void OnModelCreatingPartial(ModelBuilder modelBuilder);"
$search += ""
$search += " }"
$search += " }"
$search | Set-Content $item.FullName
}
@meurig Re-opening this issue as a feature request for adding a partial method to OnModelCreating
in the DbContext
class.
{{{on-model-creating}}}
just adds the entire method that is generated by EF Core scaffolding.I think the easiest way to deal with this scenario is for you to create a partial
DbContext
derived class, then include theOnModelCreating
override there and do whatever you need to do.If, however, you want to generate the code for this method, then extend
HbsCSharpDbContextGenerator
in a NET Standard 2.0 class library and overrideGenerateOnModelCreating
. You would then need to register your class inScaffoldingDesignTimeServices.ConfigureDesignTimeServices
. Then you'll have full control -- although this approach requires more effort. :)
Hello extending the 'HbsCSharpDbContextGeneror' is exactly the thing I need right now. I currently created some custom handlebar helpers via AddHandlebarsBlockHelpers in ConfigureDesignTimeServices. Im just wondering what is meant by:
"You would then need to register your class in ScaffoldingDesignTimeServices.ConfigureDesignTimeServices
". Does this mean I have to register this for dependency injection?
@JochemVH1 Yes precisely. Call services.AddSingleon in DesignTimeServices class.
@tonysneed might be a stupid question but do I need to remove the standard implementation? pointing to ICSharpDbContextGenerator? Somehow my derived class doesnt get hit while debugging
@tonysneed nevermind I had to make a call to register the class after the call to AddHandleBarsScaffoling
great it works now, so glad I stumbled across this post
@JochemVH1 For further reference, and for others trying this approach, please see Full Control: Extend Handlebars Generators in my EF Core Community Standup demo.
This library is the bomb! This has greatly simplified my database-first workflow. Thank you!
I want to add some code at the end of the generated
OnModelCreating
function (to deal with DateTime kinds). Is there a way to add that to the template? InDbContext.hbs
I see{{{on-model-creating}}}
, but I'm not clear on if there's a way to extend or add to that.Or is there a way to add a
.HasConversion
line to every generated DateTime field?