Updating Multiple Databases MVC 5 - asp.net-mvc

I have two contexts working with visual studio 2013. The one for the IdentityModel and another context I created for the main database. The problem I am having is whenever I run the update-database in the package manager console, it creates the ApplicationDBContext DB in both. The one for my main database never gets created because it seems it sees it as the ApplicationDBContext. I have tried Enable-Migrations -ContextTypeName DI_MVC.Models.DIDBContext and it does not create the main database tables for the DIDBContext class. I was able to do this in visual studio 2012 without an issue in creating the database. That was without the ApplicationDBContext though. Any help on what I am doing wrong would be greatly appreciated.
Below are my 2 code files. The normal IdentityModel and my DIDBContext class I created. Also I will display the web.config file as well with the database connections. There are 2 .mdf files that get created within the App_Data folder but both databases contain the membership tables.
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace DI_MVC.Models
{
public class DIDBContext : DbContext
{
public DIDBContext()
: base("DIDBContext")
{
}
public DbSet<DI_ConnectionStrings_CSI> CSIs { get; set; }
public DbSet<DI_DropDownValues_DDV> DDVs { get; set; }
public DbSet<DI_Types_DIT> DITs { get; set; }
public DbSet<DI_FORM_DIF> DIFs { get; set; }
public DbSet<DI_FormTabs_DFT> DFTs { get; set; }
public DbSet<DFI_FormSections_DFS> DFSs { get; set; }
public DbSet<DI_FormElements_DFE> DFEs { get; set; }
public DbSet<DI_DFE_DFS_DDD> DDDs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<DI_DFE_DFS_DDD>().HasKey(k => new { k.DDD_DFS_ID, k.DDD_DFE_ID });
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace DI_MVC.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
public DateTime BirthDate { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
}
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-DI_MVC-meohmeohmy.mdf;Initial Catalog=aspnet-DI_MVC-meohmeohmy;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="DIDBContext" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-DI_MVC-MainDB.mdf;Initial Catalog=aspnet-DI_MVC-MainDB;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>

You're not alone. It would make sense that if you enabled migrations for a single DbContext it would only update the DbContext that migrations are enabled for or at least let you specify which DbContext you wanted to update. However, that is not the case.
Read - this and this.
TLDR Enable-Migrations –EnableAutomaticMigrations

Related

The dbo.ASPNetUser and the other tables like this don't appear in my Server Explorer

I am working in my MVC5 project and I have created a DbContext different to the ApplicationDbContext but it inherits from the same class. I have been developing some parts of my project but now I want to add all the authentication and authorization stuff. But the tables that ASP.NET creates automatically for this purpose don't show up in my Server Explorer although I can work with the sets named Users and Roles of my context. I have searched the reasons of this but I found nothing useful. I hope someone can answer my question and whether it is an important issue or not. I add the code of my DbContext class. Sorry for my English cause I know it is terrible.
namespace GestionPaladares.Models
{
using System;
using System.Data.Entity;
using System.Linq;
using System.Data.Entity.ModelConfiguration.Conventions;
using GestionPaladares.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
public class PaladarContext : IdentityDbContext<ApplicationUser>
{
// Your context has been configured to use a 'CodeFirstDatabaseModel' connection string from your application's
// configuration file (App.config or Web.config). By default, this connection string targets the
// 'GestionPaladares.Models.CodeFirstDatabaseModel' database on your LocalDb instance.
//
// If you wish to target a different database and/or database provider, modify the 'CodeFirstDatabaseModel'
// connection string in the application configuration file.
public PaladarContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
// Add a DbSet for each entity type that you want to include in your model. For more information
// on configuring and using a Code First model, see http://go.microsoft.com/fwlink/?LinkId=390109.
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<FoodAndDrink> Foods { get; set; }
public virtual DbSet<SoldBill> SoldBills { get; set; }
public virtual DbSet<CostBill> CostBills { get; set; }
public virtual DbSet<Seller> Sellers { get; set; }
public virtual DbSet<Grocer> Grocers { get; set; }
public virtual DbSet<Owner> Owners { get; set; }
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Measure> Measures { get; set; }
public virtual DbSet<Edge> Edges { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Add ApplicationUser in Dbcontext
public DbSet<ApplicationUser> ApplicationUser { get; set; }
For example,
namespace GestionPaladares.Models
{
using System;
using System.Data.Entity;
using System.Linq;
using System.Data.Entity.ModelConfiguration.Conventions;
using GestionPaladares.Models;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
public class PaladarContext : IdentityDbContext<ApplicationUser>
{
// Your context has been configured to use a 'CodeFirstDatabaseModel' connection string from your application's
// configuration file (App.config or Web.config). By default, this connection string targets the
// 'GestionPaladares.Models.CodeFirstDatabaseModel' database on your LocalDb instance.
//
// If you wish to target a different database and/or database provider, modify the 'CodeFirstDatabaseModel'
// connection string in the application configuration file.
public PaladarContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
// Add a DbSet for each entity type that you want to include in your model. For more information
// on configuring and using a Code First model, see http://go.microsoft.com/fwlink/?LinkId=390109.
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<FoodAndDrink> Foods { get; set; }
public virtual DbSet<SoldBill> SoldBills { get; set; }
public virtual DbSet<CostBill> CostBills { get; set; }
public virtual DbSet<Seller> Sellers { get; set; }
public virtual DbSet<Grocer> Grocers { get; set; }
public virtual DbSet<Owner> Owners { get; set; }
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Measure> Measures { get; set; }
public virtual DbSet<Edge> Edges { get; set; }
public DbSet<ApplicationUser> ApplicationUser { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Since you are using EF, you should first add migration, then do update database from the PM console window. Take a note you have to select the correct project form the list and be sure of the right connection string in your code or appsettings file.
Or, you have to create your own method to call on startup for fixing the database for you.
public static void EnsureDatabaseCreated(IConfiguration configuration)
{
using (var context = new DatabaseContext(configuration.GetConnectionString(GlobalConstants.APP_SETTINGS_CONNECTION_NAME)))
{
context.Database.Migrate();
}
}
public Startup(IConfiguration configuration, IHostingEnvironment environment)
{
EnsureDatabaseCreated(this.configuration);
}
Change the DatabaseContext class name with yours.
Hope this helps.

Error: The entity type ApplicationUser is not part of the model for the current context [duplicate]

I'm migrating from Identity 1.0.0 to Identity 2.0.1 following this article
and the migrations code generated is nothing about the new IdentityUser. It doesn't add the new columns.
So I made a new project and tried again but the migrations codes is empty.
To fix that problem, I did the edits directly in SQL Server and imported my database again in my solution.
Now my AspNetUser is exactly the same as my IdentityUser as you can see
IdentityUser
public virtual int AccessFailedCount { get; set; }
public virtual ICollection<TClaim> Claims { get; }
public virtual string Email { get; set; }
public virtual bool EmailConfirmed { get; set; }
public virtual TKey Id { get; set; }
public virtual bool LockoutEnabled { get; set; }
public virtual DateTime? LockoutEndDateUtc { get; set; }
public virtual ICollection<TLogin> Logins { get; }
public virtual string PasswordHash { get; set; }
public virtual string PhoneNumber { get; set; }
public virtual bool PhoneNumberConfirmed { get; set; }
public virtual ICollection<TRole> Roles { get; }
public virtual string SecurityStamp { get; set; }
public virtual bool TwoFactorEnabled { get; set; }
public virtual string UserName { get; set; }
IdentityUser.cs
public class ApplicationUser : IdentityUser
{
public bool Has_accepted_policy { get; set; }
public int user_type_id { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
AspNetUser
public string Id { get; set; }
[Required]
[StringLength(256)]
public string UserName { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
[StringLength(256)]
public string Email { get; set; }
public bool EmailConfirmed { get; set; }
public bool Is_Active { get; set; }
[Required]
[StringLength(128)]
public string Discriminator { get; set; }
public int? user_type_id { get; set; }
public bool Has_accepted_policy { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public bool TwoFactorEnabled { get; set; }
public DateTime? LockoutEndDateUtc { get; set; }
public bool LockoutEnabled { get; set; }
public int AccessFailedCount { get; set; }
... other virtual properties
and when I try to register a user I have the following exception
The entity type ApplicationUser is not part of the model for the current context
at this line
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
My startup.Auth.cs
UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());
And in my AccountController I declare my UserManager like this
public AccountController()
: this(Startup.UserManagerFactory(), Startup.OAuthOptions.AccessTokenFormat)
{
}
public AccountController(UserManager<ApplicationUser> userManager,
ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
{
UserManager = userManager;
AccessTokenFormat = accessTokenFormat;
}
public UserManager<ApplicationUser> UserManager { get; private set; }
I haven't changed anything except the new properties in the AspNetUser class and it used to work well before the migration.
There's a similar issue on CodePlex marked as fixed but they don't give the solution
Does anyone know how to fix this?
EDIT
To be sure I didn't do any mistakes when I edited my SQL database. I created another project and generated an Identity database and I changed the connection string for that database and I still have the same error.
SOLUTION
When I have edited my database I haven't noticed that in Identity 2.0.0 they changed the User_Id for UserId in AspUserClaims table. After doing that I had the same error but then I did what tschmit007 said about adding the ApplicationDbContext to the UserStore constructor and now it works.
UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
I was having this same problem. I’m doing database first development with an EDMX file. If you are using the connection string generated when adding the EDMX file in :base(“EDMXConnString”) you will most likely have this problem.
I fixed this by creating a standard connection string that pointed to the database where the ASP.NET Identity tables are.
<add name="MyConnString" connectionString="Data Source=server; Initial Catalog=db_name; User ID=user_id; Password=password; Connect Timeout=60;" providerName="System.Data.SqlClient" />
And then used that connection string in :base, and it worked!
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("MyConnString")
{
}
}
for me it seems to miss a context instanciation:
UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());
should be
UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
My problem was I tried to use generated ADO.NET connection string for both generated and authentication context ApplicationDbContext. I fixed it by using a separate connection string for authentication. Also pay attention to the provider - for authentication context it has to be System.Data.SqlClient:
<add name="DefaultConnection" connectionString="Server=qadb.myserver.com;Database=mydb;User Id=myuser;Password=mypass;" providerName="System.Data.SqlClient" />
If you are using code first, check your connection string to ensure providerName is 'SqlClient' as in providerName="System.Data.SqlClient
If you are using database first, check your connection string to ensure providerName is 'EntityClient' as in providerName="System.Data.EntityClient
Same problem to me, it solved by this code:
public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false)
{
Database.Connection.ConnectionString = #"data source=...;initial catalog=...;user id=...;password=...;multipleactiveresultsets=True;application name=EntityFramework";
}
I also received this error message, but the cause and solution were different. In my case, I had introduced a new Id property of type Guid in my ApplicationUser class. Perfectly valid C# syntax, but it apparently created massive confusion for the Identity or EntityFramework core that relies on reflection to find stuff.
Removing the new Id property in my ApplicationUser class resolved this error.
I ran into this issue and it was an object name conflict. The IdentityConfig.cs was using ApplicationUser, but it was using the auto-generated IdentityModels.ApplicationUser instead of my own context's DataAccess.ApplicationUser. Made perfect sense once I found it. So, I deleted the auto-generated IdentityModels.cs from the base WebAPI template - not using that anymore anyway - then I added the using statement in IdentityConfig.cs to my own DataAccess namespace and voila, proper mapping. If you forget the template built a lot of this for you, you'll run into the issue:
public class ApplicationUserManager : UserManager<ApplicationUser> // the name conflict
{
public ApplicationUserManager(IUserStore<ApplicationUser> store)
: base(store)
{
}
My issue was that I had created a new DbContext, but it wasn't inheriting from IdentityDbContext.
An easy fix...
public partial class GoldfishDbContext : IdentityDbContext<ApplicationUser>
{
....
}
I am sure not why this happens, my solution works perfectly fine, tested everything before I sleep. After 12 hours, I checked it again and run and this was exactly the same error. I tried almost all solutions here in SO but none of them works.
I am implementing a database approach here. Then suddenly there was this
DefaultConnection
on my web.config that Visual Studio generated when I first created the solution. So I've used it instead of the connection string that was generated by my EDMX file and suddenly it works!
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
This was my connection string that works:
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-System.WEB-20180718085411.mdf;Initial Catalog=aspnet-System.WEB-20180718085411;Integrated Security=True" providerName="System.Data.SqlClient" />
Originally I am using this that was generated by my EDMX file but suddenly the website doesn't work although it works before. I didn't change anything and all code was in TFS, so I am 100% sure it works and I did a full restore and get the latest version:
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-System.WEB-20180718085411.mdf;Initial Catalog=aspnet-System.WEB-20180718085411;Integrated Security=True" providerName="System.Data.SqlClient" />
This happened to me because I was trying to wire up ApplicationUserManager and some other related dependencies using my dependency injection container. In some cases, the container resolved ApplicationDbContext in other cases the built-in injector in Owin would resolve it.
The easiest way to make sure this doesn't happen is to not try to wire up any of the Auth stuff using your DI container of choice unless you really know what youre doing with DI...otherwise just let Owin resolve it using the built in injector.
In other words, remove anything like:
builder.RegisterType<ApplicationUserManager>().InstancePerRequest();
And just let Owin resolve it the way it was built in:
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}

EntityException in MVC4

I am new to MVC and i am having a problem. I have one table named tblEmployee , model Employee. Controller EmployeeController. i am having EntityException in my EmployeeController controller.
My code for Model:
namespace MvcPractice.Models
{
[Table("tblEmployee")]
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
}
}
i have created EmployeeContext.cs in Model:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace MvcPractice.Models
{
public class EmployeeContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
}
}
Connection string:
<connectionStrings>
<add name="EmployeeContext"
connectionString="server=.;database=MvcDemo; integrated security=SSPI;"
providerName="System.Data.SqlClient"/>
</connectionStrings>
This is a web application but you are using integrated security to connect. That will use the identity of your web application. It's preferable to use a real SQL Server user created for your application. So create a user and change your connection string to something like this:
server=.;database=MvcDemo;User ID=<username>;Password=<password>;
Additionally, it's unusual for a local installation of SQL Server to be installed with an empty instance name, so you may also need to check that the server name shouldn't be this, just check what your SQL Server Management Studio is using to connect:
.\sqlexpress

use multiple dbContext in one application

I am struggling with using multiple dbContext with an single web application in ASP.NET MVC 5. I am following code First existing database design approach.
i need guideline how to do that say in example if i am creating 5 models using ADO.NET, it will create 5 dbContext along with its model classes.
how it will change in web.config file?
Many Thanks
public partial class DefaultContext : DbContext
{
public DefaultContext()
: base("name=DefaultContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<AspNetRole> AspNetRoles { get; set; }
public virtual DbSet<sys_Actions> sys_Actions { get; set; }
public virtual DbSet<sys_ActionsInRole> sys_ActionsInRole { get; set; }
public virtual DbSet<sys_Controllers> sys_Controllers { get; set; }
public virtual DbSet<sys_Functions> sys_Functions { get; set; }
public virtual DbSet<sys_FunctionsHierarchy> sys_FunctionsHierarchy { get; set; }
}
basically for each dbContext you need to add a new connection string with unique name in the connectionStrings section in your web.config file
here is an example:
<connectionStrings>
<add name="dbContext1" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=dbServer;initial catalog=db1;integrated security = true;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
<add name="dbContext2" connectionString="metadata=res://*/Model2.csdl|res://*/Model2.ssdl|res://*/Model2.msl;provider=System.Data.SqlClient;provider connection string="data source=dbServer;initial catalog=db1;integrated security = true;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>

Mapping EF 4.1 code-first models to database tables

I have been trying the model-first method when designing my application. We usually like to add a prefix to our tables in larger databases so it is easier to find stuff. For example:
sc_ = Shopping cart tables
wb_ = Water billing tables
ea_ = Employment Application tables
The class I have setup looks like this so far.
public class EFDbContext : DbContext
{
public DbSet<Transaction> Transactions { get; set; }
public DbSet<TransactionItem> TransactionItems { get; set; }
public DbSet<Response> Response { get; set; }
}
Web.config (set currently for local database testing):
<add name="EFDbContext" connectionString="Data Source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=database" providerName="System.Data.SqlClient"/>
What do I need to change so that the Transaction object gets linked to the sc_Transactions table? I haven't seen in my searching that clarifies this.
As a second question, do I have to manually create my tables?
You can override the OnModelCreating method from DbContext in your EFDbContext class:
public class EFDbContext : DbContext
{
public DbSet<Transaction> Transactions { get; set; }
public DbSet<TransactionItem> TransactionItems { get; set; }
public DbSet<Response> Response { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Transaction>().MapSingleType().ToTable("someTableNameHere");
}
}
See this post for more info.
You can use System.ComponentModel.DataAnnotations like so:
[Table("tblUser")]
public class User
{
public int ID { get; set; }
public string Name { get; set; }
}
Or with EF 4 you can override the OnModelCreating method to map your tables, which is quite powerful thing as you can map and adjust many things at once.
public class MyContext: DbContext
{
DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().MapSingleType().ToTable("tblUser");
}
}
For more info see:
EF4 CF custom database mapping
EF keynotes from the Build2011 event (custom mappings are at about
15 min or so)

Resources