EntityFramework update-database multiple databasecontexts adding table not creating database - entity-framework-core

I have two separate database contexts and expect to have a database for each database context.
When I do entityfirst migrations why is it not creating separate databases?
Instead, one of the database contexts is creating a table inside of the other context even though I am specifying the -context parameter explicitly.
appsetting.json
"ConnectionStrings": {
"BuildAppDb": "Server=DESKTOP-BJR3FMP\\SQLEXPRESS;Database=EasyBuilderApp;Trusted_Connection=True;",
"LicenseKeyDb": "Server=DESKTOP-BJR3FMP\\SQLEXPRESS;Database=EstiframeSoftwareLicenser;Trusted_Connection=True;"
},
contexts
public partial class BuildAppDbContext : DbContext
{
public BuildAppDbContext(DbContextOptions<BuildAppDbContext> options)
: base(options)
{
}
public DbSet<PartCompletion> PartCompletions { get; set; }
}
public class LicenseKeyDbContext : DbContext
{
public LicenseKeyDbContext(DbContextOptions<LicenseKeyDbContext> options)
: base(options)
{
}
public DbSet<LicenseReg> RegLicenses { get; set; }
}
startup.cs
Configuring services
//DATABASE CONNECTIONS
string connectionString = _configuration.GetConnectionString("LicenseKeyDb");
services.AddDbContext<LicenseKeyDbContext>(options => options.UseSqlServer(connectionString));
connectionString = _configuration.GetConnectionString("BuildAppDb");
services.AddDbContext<BuildAppDbContext>(options => options.UseSqlServer(connectionString));
package manager console commands
add-migration -context BuildAppDbContext
update-database -context BuildAppDbContext
add-migration -context LicenseKeyDbContext
update-database -context LicenseKeyDbContext
RESULT ?? WHY
It is adding a table to the EasyBuilderApp database when it should be adding an entire database for the EstiframeSoftwareLicenser database

I figured out my problem.
I literally had to use a separate string variable here:
.AddDbContext method is executed later, not at that exact moment so using the same variable to store the connection string does not work.

Related

i have issue with migrations

i have issue with migration
my problem is i have class name Db context but when i start to enable migration nuget say:
No context type was found in the assembly 'MyCms.DataLayer
also DataLayer is my deafualt project
also i inject conection string in startup with appsettings.json
public class MyCmsDbContext : DbContext
{
public MyCmsDbContext(DbContextOptions<MyCmsDbContext> options) : base(options)
{
}
public DbSet<PageGroup> PageGroups { get; set; }
public DbSet<Page> Pages { get; set; }
acctuly i found it.the problem was with nuget package
i forgot to inistall entityframwork.tools
if you have multiple layers and data layer is distinct from startup project(UI) you can use this command :
dotnet ef migrations add InitialMigration --project "MyCms.DataLayer" --startup-project "MyCms.WebUI"
edit startup configuration :
services.AddDbContext<ApplicationContext>(option =>
option.UseSqlServer(Configuration.GetConnectionString("Default"),
assembly => assembly.MigrationsAssembly(typeof(ApplicationContext).Assembly.FullName)));

Entity Framework Code First Initial Create

I first time trying to create web app (.net core 2.1) from scratch with Entity Framework. For some reason I can't get DB generated.
So I installed EF nuget. And did next things:
Added class that inheres from DbContext:
public class ApplicationDbContext:DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Server> Servers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Server>().HasData(
new Server
{
Name = "My Server",
InUse = false
}
);
}
}
And created Entity:
public class Server
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public bool InUse { get; set; }
}
In startup.cs in ConfigureServices method I added:
var connectionString = Configuration.GetConnectionString("ApplicationConnection");
services.AddDbContext<ApplicationDbContext>
(options => options.UseSqlServer(connectionString));
Connection string coming from appsettings and I debugged it so it does coming through, and it same string that I using in other projects with just different Database name value and it should be ok.
Also I run from console Add-Migration command so I got Migrations folder with InitialCreate migration and some snapshot file.
But when I run app I don't get any error but it never hit break point inside InitialCreate.cs migration and so never create DB.
Any ideas where and what should I call to trigger those?
If you want entity framework automatically creates your database
In Configuration file, add this line in constructor:
AutomaticMigrationsEnabled = true;
Then add the code into DBContext:
Database.SetInitializer(new
DropCreateDatabaseAlways<YourDbContext>());
Then when the application already ran:
Database.SetInitializer(new
DropCreateDatabaseIfModelChanges<YourDbContext>());
You can also have a look MigrateDatabaseToLatestVersion
If you manually track version of database:
Update AutomaticMigrationsEnabled = false;
From console, run command Update-Database to migrate your database
manually
So I been able to create DB by adding next code inside Startup.cs in Configure() method
using (var scope = app.ApplicationServices.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
dbContext.Database.Migrate();
if (!dbContext.Servers.Any())
{
dbContext.Servers.Add(new Server
{
Name = "My Server",
InUse = false
});
dbContext.SaveChanges();
}
}

Unable to query new table from asp.net core web application using EF 1.0

I have developed a new asp.net Core web application using Visual Studio 2015. I am at the point where I am adding user customization options by adding additional tables to my local database. However I have been unable to add whatever EF needs to query a new table correctly. I get the following error when attempting to query the table..
Applying existing migrations for ApplicationDbContext may resolve this issue
There are migrations for ApplicationDbContext that have not been applied to the database
•00000000000000_CreateIdentitySchema
Apply Migrations
In Visual Studio, you can use the Package Manager Console to apply pending migrations to the database:
PM> Update-Database
Alternatively, you can apply pending migrations from a command prompt at your project directory:
dotnet ef database update
My table is a simple table with a few varchar or nvarchar columns. The model looks something like...
namespace MyNamespace.ColorSchemes
{
public class ColorSchemesViewModel
{
[Required]
public string Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string bc { get; set; }
}
Table looks something like this in SQL Server...
CREATE TABLE [dbo].[ColorSchemes](
[Id] [nvarchar](50) NOT NULL,
[Name] [varchar](32) NOT NULL,
[bc] [nchar](7) NOT NULL
)
I have added the table to the application context like such...
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<ColorSchemesViewModel> Colors { get; set; }
I have also used as separate class similarly like..
public DbSet<ColorSchemes> Colors { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> 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);
}
}
I have added the context to a controller like this...
private ApplicationDbContext _context;
public MyController(IMemoryCache memoryCache, ILoggerFactory loggerFactory, ApplicationDbContext context)
{
_memoryCache = memoryCache;
_logger = loggerFactory.CreateLogger<ChordMVCController>();
_context = context;
}
I have tried to query the table in my controller like this...
var colorSchemes = (from c in _context.Colors
select c).ToList();
I have attempted to use the Package Manager to per instructions from the error...
PM> Update-Database
I always get this error...
System.Data.SqlClient.SqlException: There is already an object named 'AspNetRoles' in the database.
This doesn't make sense since this table is already in the database and the EF definition. How do I get my table added properly to the EF migrations so I can query it?
I was able to solve this myself...
I created a different context rather than trying to embed the dbset in the default ApplicationDbContext and also removed the onModelCreating method.
public class ColorSchemeDbContext : DbContext
{
public ColorSchemeDbContext(DbContextOptions<ColorSchemeDbContext> options) : base(options)
{
}
public DbSet<ColorScheme> ColorSchemes { get; set; }
}
Replaced the ApplicationDBContext with the new context in my controller class...
private readonly ColorSchemeDbContext _context;
public MyController(IMemoryCache memoryCache, ILoggerFactory loggerFactory, ColorSchemeDbContext context)
{
_memoryCache = memoryCache;
_logger = loggerFactory.CreateLogger<ChordMVCController>();
_context = context;
}
After that the query worked. I spent a lot of time attempting to use the EF migrations to create the tables from a class syntax. Nothing seemed to work. I was creating a new .NET CORE web application in VS 2015 with the template and using user authentication which creates the AspNetRoles tables in SqlLite once you do an update-database. It is very confusing how to add additional tables using a code first approach after that. A lot more documentation is needed regarding EF migrations with respect to managing projects over time. I see the benefits of having all of your database updates maintained from your VS project but it is not easy to understand.

Database changes are not vsiisble after executing migrate.exe

I am using entity framework 6.1. I used code-based migration i.e. Migrate.exe to update my database (Add a new property to table). Migrate.exe executed fine and I did refresh on my SQL Server database but the newly added column was not visible.
I inserted a row into the table and checked table and found that now newly column is added to the table.
I would like to know why this newly created column not visible immediately after executing migrate.exe and why I have to hit database to see my update model changes?
Please respond.
I have used below database context and initializer.
public class AMLDBContext : DbContext
{
public DbSet<Template> Templates { get; set; }
public DbSet<Property> Properties { get; set; }
public AMLDBContext()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<AMLDBContext, Migrations.Configuration>());
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Property>().HasKey(s => new { s.PropertyName, s.TemplateId });
modelBuilder.Entity<ReturnAttribute>().HasKey(s => new { s.AttributeName, s.TemplateId });
base.OnModelCreating(modelBuilder);
}
}
I used below command for migrate.exe.
migrate.exe AutoDbUpgrade.exe /StartUpDirectory:"C:\TestProject\AutoDbUpgrade\AutoDbUpgrade\bin\Debug" /startupConfigurationFile=”AutoDbUpgrade.exe.config” /verbose

Using EF code-first migrations when design model is DB first?

Real question seems to be here is which is the best way to refresh code first model from DB
Any downsides or alternatives how one could use code first migrations when domain model must reflect DB changes? (eg. in case MDS)
Option 1:
I have tried making POC of migration context is inherited from CodeFirstFromDB context directly.
When one generates EF model from Database the model is separated from migration context eg. dbcontext is not aware that such migrations exist.
Migrations have been enabled for Migration Context only and therefore it will only track changes on it own resx.
public class MigrationInheritedDBContext : ModelCodeFirstFromDB
{
public MigrationInheritedDBContext() : base("name=MigrationInheritedDBContext ")
{
}
}
public partial class ModelCodeFirstFromDB : DbContext
{
public ModelCodeFirstFromDB()
: base("name=ModelCodeFirstFromDB")
{
}
public ModelCodeFirstFromDB(string connectionString) : base(connectionString)
{
}
public virtual DbSet<DMObject1> DMObject1 { get; set; }
public virtual DbSet<DMObject2> DMObject2 { get; set; }
public virtual DbSet<DMObject3> DMObject3 { get; set; }
.
.
.
.
Option 2:
There are T4-templates that will generate db context directly from database.
Any notes, opinions, alternative approaches are welcome, thank you.