use multiple dbContext in one application - asp.net-mvc

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>

Related

What is wrong with my Entity Framework and architecture?

I am developing a task tracker web app and you could see the full code here: https://github.com/KimSergey94/TaskTracker
In short, admin, manager, client and employee are users of the app and admin is the boss of these roles. To illustrate, a manager can create a task received by a client and assign it to an employee. The task includes Statuses and Statuses includes Comments. The "roles" have user id as a foreign key to the User table that stores their email addresses and passwords. The Role table stores user id so that they have their roles right.
I need to develop basic functionality, make use some of AJAX, custom filters, stored procedures. There is something wrong with my authorization and roles logic. So, I would appreciate if you take a look and inform me about anything that you feel is not right.
Currently, when I am trying to launch the app and initialise the database, I get the following error:
System.Data.SqlClient.SqlException: 'Introducing FOREIGN KEY constraint 'FK_dbo.Employees_dbo.Users_UserId' on table 'Employees' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
User and Employee classes code:
public class User
{
public int UserId { get; set; }
[DataType(DataType.EmailAddress)]
[Required]
public string Email { get; set; }
public string Password { get; set; }
public int RoleId { get; set; }
}
public class Employee
{
public int EmployeeId { get; set; }
//[Required(ErrorMessage = "First Name is required")]
public string FirstName { get; set; }
//[Required(ErrorMessage = "Last Name is required")]
public string LastName { get; set; }
//[Required(ErrorMessage = "Country field is required")]
public string Country { get; set; }
public string Position { get; set; }
public int Salary { get; set; }
public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual User User { get; set; }
//public virtual ICollection<Task> Tasks { get; set; }
}
Globals.asax
protected void Application_Start()
{
System.Data.Entity.Database.SetInitializer<TaskTrackerContext>(new TaskTrackerDbInitializer());
var db = new TaskTrackerContext("TaskTrackerContext");
db.Database.Initialize(true);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ModelValidatorProviders.Providers.Clear();
NinjectModule orderModule = new OrderModule();
NinjectModule serviceModule = new ServiceModule("TaskTrackerDb");
var kernel = new StandardKernel(orderModule, serviceModule);
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
}
web.config:
<connectionStrings>
<add name="TaskTrackerContext"
connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename='|DataDirectory|\TaskTrackerContext.mdf';MultipleActiveResultSets=True; Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<!--
Initial Catalog=FormsAuth;
</appSettings>
By the way why do I need this Initial Catalog=FormsAuth;?
I noticed that with this parameter I could not instantiate database.
I want to get Include functionality for my models
In the EF Core, You should disable cascade delete with DeleteBehavior.Restrict or DeleteBehavior.SetNull, e.g. in the database context class, enter a new method
protected override void OnModelCreating(ModelBuilder modelBuilder){
modelBuilder.HasOne(x => x.Employee).WithMany().HasForeignKey(x =>
x.UserId).OnDelete(DeleteBehavior.Restrict)
}
If you want cascade behavior, you need to add a nullable integer to the UserId:
public int? UserId { get; set; }
Initial Catalog=FormsAuth; is from the System.Web.Security namespace and is used for form validations, you can read more about it on the Microsoft Docs: https://learn.microsoft.com/en-us/dotnet/api/system.web.security.formsauthentication?view=netframework-4.8
I recommend using asp.net identity, I can see a lot of what you are doing is re-inventing the wheel, whereas asp.net does the authentication and validation for you. You can read about it here: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-3.0&tabs=visual-studio
I had a table that had a circular relationship with others and I was getting the same error. Turns out it is about the foreign key which was not nullable. If the key is not nullable related object must be deleted and circular relations doesn't allow that. So use a nullable foreign key.
public int? UserId { get; }
[ForeignKey("UserId")]
public virtual User User { get; set; }

Keyword not supported error in Enabling migrations

I have a dbcontext class where i have initialized 4 dbsets. My connection string is
<connectionStrings>
<add name="somename" connectionString="Data Source=.; initial catalog=someDb; user ID=ab; Password:111111; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
My dbcotext class is
public AstroEntities(): base("somename")
{
Database.SetInitializer<AstroEntities>(new CreateDatabaseIfNotExists<AstroEntities>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Contact>().ToTable("Contacts");
modelBuilder.Entity<Appointment>().ToTable("Appointments");
modelBuilder.Entity<Consultation>().ToTable("Consultations");
modelBuilder.Entity<HomePageMessage>().ToTable("HomePageMessages");
base.OnModelCreating(modelBuilder);
}
public DbSet<Contact> Contacts { get; set; }
public DbSet<Appointment> Appointments { get; set; }
public DbSet<Consultation> Consultations { get; set; }
public DbSet<HomePageMessage> Homepagemessages { get; set; }
}
When i enable automatic migrations iam getting error as follows
"Keyword not supported: 'password:111111; multipleactiveresultsets'."
Can someone say whats the problem?
Your Connection String format is wrong, it should be like this
connectionString="Data Source=.; initial catalog=someDb; user ID=ab; Password=111111; MultipleActiveResultSets=True;"

Updating Multiple Databases MVC 5

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

Error in webconfig file

I am new to MVC 4.I am working on a tutorial which i found on browsing the internet and I am trying to add a model to my application.I have created one and when i try to add a controller it gives me a error message like..
Unable to retrive metadata for 'Practice.Models.Customer'.Invalid value for Key 'attachdbfilename'.
MODEL:
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public int Amount { get; set;}
}
public class CustomerDBContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
}
Connection string:
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-practice-20130320183458;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
<add name="CustomerDBContext"
connectionString="Data Source=(LocalDB)\\v11.0;AttachDbFilename=|DataDirectory|\Customers.mdf;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
I think there is some problem with ConnectionString but dont know where is it.Please help me solve this problem..Thanks in advance
I think you have to make your enity virtual.
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual int Amount { get; set;}

MVC 3 - DB Context - Web.Config

How can I share my DBcontext in my web.config without creating multiple connections?
WEB.config:
<configuration>
<connectionStrings>
<add name="daC_Companies" connectionString="Data Source=10.0.2.100;Initial Catalog=XXXXX;User ID=XXXXXXXXXx;Password=XXXXXXXX;Persist Security Info=False" providerName="System.Data.SqlClient" />
</connectionStrings>
Data Access:
public class daC_Companies : DbContext
{
public DbSet<ClassLibrary.Companies.C_Companies> dbsetC_Companies { get; set; }
}
And then I have a class called C_Companies referenced above. It works fine but I don't want to have a new DBContext for every class I want to access.
The DbContext should be specific to the database, not to the object. To add a reference to more db tables, add them as properties into the daC_Companies object:
public class daC_Companies : DbContext
{
public DbSet<ClassLibrary.Companies.C_Companies> dbsetC_Companies { get; set; }
public DbSet<ClassLibrary.Companies.Object2> Object2s { get; set; }
public DbSet<ClassLibrary.Companies.Object3> Object3s { get; set; }
public DbSet<ClassLibrary.Companies.Object4> Object4s { get; set; }
}

Resources