Entity Framework Core - Changing Database Schema at runtime without running migration - entity-framework-core

I have a .NET Core 5 application with Entity Framework (code first) with migrations and Azure SQL database.
I want to run two separate applications on same DB with different data. I want to have test and demo application. My idea was to change schema for each application. One application will have schema "test." and another one "demo.".
I tried to do this with this article
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("demo");
}
Problem is that I need to run Add-Migration with this approach. And I don't want to do that.
There is also another way that I didn't try. Described here
Problem there is that I need to create EntityConfiguration for each Entity and I don't want to do this neither.
I want to set schema globally for all tables at once.
Is there a way how to do this without creating new migrations? Or is there a better way without changing scheme?

Related

Database first with Identity in .NET Core and Entity Framework Core

I would like to use a Database First approach to managing my database with EF Core, and not just for the initial database creation. I'm using this command to generate my entity models and mapping code:
Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=MyDB;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models/Entities -f
Now this works fine. I'm just struggling with identity integration. Currently I have two separate contexts, the one generated by the scaffolding command and an identity context that looks like this:
public class IdentityContext : IdentityDbContext<ApplicationUser> {
public IdentityContext(DbContextOptions<IdentityContext> options)
: base(options) {
}
protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
Both contexts read from the same database and are registered like this:
services.AddDbContext<ApplicationContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<IdentityContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
Is it reasonable to have two separate contexts? Will it cause future problems as I start creating relationships between users and other models? I couldn't find anything in the docs regarding continued use of db-scaffold to generate my entity models and mappings.
Let me know if I can clarify anything.
ORIGINAL CONTEXT
Okay so clearly my original question wasn't any good.
I'd just like some clarification on if my Database First workflow with .NET Core and Entity Framework is the right way. I've read all the articles I can find about using Database First, which all seem to end with: "now you have scaffolded your database so can start using Code First migrations". I want to continue writing my SQL and just keep mapping it to entities.
To manage and update my application I'm using the excellent DbUp project. So I write my scripts, apply them to the database
This appears to be working fine so far. My only problem is integrating identity nicely. Currently I just have two contexts, my application one and an identity one. My application one has also mapped all the identity tables. It is working fine but I'm not sure what will happen going forward as I start linking tables to the user... I believe I did make it work with one context but I had to modify the generated application context each time, removing all the Identity mappings and inheriting from IdentityDbContext (to generate the identity mappings). I could change the schema of the identity tables/my tables and just generate the mappings for my tables, excluding the identity tables. Then I will probably need to manually write mapping properties on ApplicationUser, is that correct?
Basically, I'm not really feeling like Database First is a first class citizen in .NET anymore. Am I just missing something obvious to have this kind of just "work" without modifying generated code? Or am I overthinking this and just need to get on with it?
Apologies for the rambling, one of those days I guess.

Entity Framework Core 2.0 Dynamically Creating A Database

I am new to EF Core, and as I tried using it I found out that you need to add migrations for it to create a database from models. My question is, do we have another option aside from migrations to dynamically create the database on run time just like what it was in EF 6?
Thanks.
Until a seeding mechanism is provided in EF Core you can provide your own seeding mechanism.
In earlier phases of a project, when the database is not yet fixed, I don't care that data get lost. When I want to recreate the database dynamically I call the function below. By the setting of a parameter I determine if this "recreateDatabase"-function is called yes or no. The function is included in MyOwnDbContext class.
The seed function you need to write is very similar to the one you use in EF 6.
private static void recreateDatabase(YourOwnDbContext dbContext)
{
dbContext.Database.EnsureDeleted();
dbContext.Database.EnsureCreated();
seed(dbContext);
}

How do I use Entity Framework in Code First Drop-Create mode?

I'm using Entity Framework v4. I have followed the instructions in the Nerd Dinner tutorial. I'm currently in development mode (not released to any higher environments) and would like for tables to be recreated on each new deployment, since the models are still highly volatile and I don't care to retain data. However, this does not occur. Tables are not created/modified, or anything happening to the DB. If I move to a migrations model by using the Package Manager commands: enable-migrations, add-migration (initial), this works and uses my migrations. However, since I don't yet want to have granular migrations and only want my initial create script, I am forced to delete the migrations folder, redo the commands (enable-migrations, add-migration) and delete the database manually, every time I change anything.
How do I get the drop/create behavior of code first to occur?
Use DropCreateDatabaseAlways initializer for your database. It will always recreate database during first usage of context in app domain:
Database.SetInitializer(new DropCreateDatabaseAlways<YourContextName>());
Actually if you want to seed your database, then create your own initializer, which will be inherited from DropCreateDatabaseAlways:
public class MyInitializer : DropCreateDatabaseAlways<YourContextName>
{
protected override void Seed(MagnateContext context)
{
// seed database here
}
}
And set it before first usage of context
Database.SetInitializer(new MyInitializer());
If the database already exists and you want to make changes to your model, you use DropCreateDatabaseIfModelChanges<YourContextName>

Entity Framework database-first and automatically setting concurrency token for all tables

I am using the entity framework (EF 4.5 using the POCO template that uses the DbContext) and I have a very large model.
Every table in the model has an integer column (named RowVersion). I want to set this column as the concurrency column automatically.
I do not want to manually do this for every table in the EDMX file. And going forward for maintenance I do not want to have to remember to do this.
I was hoping there was something I could add to the context to do this automatically for all tables for me.
I seen this piece of code on another post
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<myEntity>().Property(x => x.RowVersion).IsConcurrencyToken();
}
But this appears to only be for code-first, as the event never gets fired for my model.
Any ideas how I could do this?

Entity Framework 4.3 migrations on existing "Shared" database

We have a huge database with different database schemas for different web applications.
For example: WebApp1 uses Schema1.Tables. WebApp2 uses Schema2.Tables and so on.
Now, I am developing a new web application (WepApp3) which will use Entity Framework 4.3.1. WebApp3 should only be concerned with Schema3 and use only those database object which are part of Schema3. If i create some Entities in WepApp3, How do i migrate these entities to database as schema3.tables? Do i still need to do Initial Migration?
Please help.
I don't think it's possible to have multiple EF models in the same database. EF shouldn't try to touch tables that are nothing to do with its model, but if you wanted to add another EF app to the same database you'd run into trouble because they'd try to share the same MetaData tables.
When generating new models using code-first, you can specify which schema they should be part in the DbContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().ToTable("MyEntity", "Schema3");
}
Is it an option to migrate your schemas out into different databases if there are no shared apps?
It seems to WORK. I started with an existing database. created an mvc app (app1) with couple of models. I then created a schema for this app in database. I specified schema for the models as per your comment. Then I used the power of code based migration script to update the database. Migration script created 2 tables under the new schema without corrupting existing stuff. I noticed EF created __MigrationHistory table with a row with change info.
Then i created another app, a new schema and repeated the migration process with a little tweak in migration script. The script had code to re-create 2 tables of app1. i deleted that code from script. EF then successfully created new tables under new schema and also created new row in __MigrationHistory table with info about new changes. All existing stuff remain unchanged including data.