In order to avoid having two databases, I have mapped my entities to ASPNETDB.MDF, which is made automatically for membership. I was following this article in order to map my entities to existing database: http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx
From what I understand all I need to do change is the name of the databse for the context class like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using UniversityApp.Models;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace UniversityApp.DAL
{
public class ASPNETDB : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Review> Reviews { get; set; }
public DbSet<Movie> Movies { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Also I have changed the connection string like this:
<connectionStrings>
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" />
<add name="MovieContext" connectionString="Data Source=|DataDirectory|aspnetdb.mdf" providerName="System.Data.SqlServerCe.4.0"/>
</connectionStrings>
Everything seems to work fine (methods to the old database, reading and writing to the databse, even the initialization data). But still when I open the connection to ASPNETDB.mdf I don't see my tables there. What am I doing wrong?
I think you're going to run into more issues here such that in general this may not be the best approach right now. That being said, to answer your actual question, DbContext is looking for a connection string with the same name as your context. That is, it's looking for a connection string named "ASPNETDB". Since your connection strings are named "ApplicationServices" and "MovieContext" DbContext is not finding either of these.
To make DbContext use a specific connection string just pass that connection string to the DbContext constructor. For example:
public class ASPNETDB : DbContext
{
public ASPNETDB()
: base("name=ApplicationServices")
{
}
...
}
Once you get this working you'll probably want to look into using Migrations to create tables in a database that already exists.
Related
Feel free to tell me that this question needs to be moved and I will move it. I just don't know where else to go for help.
My current work flow is:
Create the database first (database Actual)
Run scaffold command which creates my models
Create a Visual Studio Database project
Import the database (database project)
Whenever I need to make a change to the database I follow the below:
Change the database project
Run a Schema Compare
Verify and update the database Actual
rerun the scaffold command with a -Force to rebuild all the models.
What (if any) type of problems am I leaving myself open to down the road?
I am not seeing the value of database migrations as I am updating the database first but using the database project to provide source control and some protection.
I always used to use the graphic database tool, but obviously with Core that is no longer an option.
I have also considered Devart's Entity Developer as a ORM.
Your thoughts and feedback are VERY much appreciated.
So the biggest problem is what happens when I need to make changes to the model.
So something simple like:
public partial class UserInfo
{
public int Id { get; set; }
[Required]
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public DateTime RecordCreated { get; set; }
}
My '[Required]' will obliviously be gone after a -force.
Joe
That is the correct "database first" workflow for EF Core, and you would not use migrations in that scenario. Be sure to place customizations to your entities or DbContext in separate partial class files so they don't get clobbered when you regenerate the entities.
always used to use the graphic database tool, but obviously with Core that is no longer an option.
With this workflow you can use any graphical design tool you want for your database schema.
I have an application which contains to context classes. One is master context class and second is sub context class. When I run the application for the first time the master database gets generated. And whenever I create a new user, a database related to that user gets generated using sub context class. For example, if I create 10 users then 10 databases will get generated using sub context class like sub_db_userId.
The problem is enabling migrations in this complex structure. I know some people would say it's not appropriate to create new database use foreign key relation but I have to work on requirements.
I found this thread very helpful in finding how to enable-migrations for separate context classes but in my scenario, it does not apply changes to existing databases because of database name is associated with user ids. Rather applying changes to existing child databases it creates new database without user id like this sub_db_. How can I solve this issue?
The way I am creating the new database for every user is given below.
My context classes:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false) {}
}
public class SubDbContext : DbContext
{
public DbSet<Country> Countries { get; set; }
public DbSet<City> Cities { get; set; }
public SubDbContext() : base("SubDatabaseConnection")
{
}
public SubDbContext(string connectionString) : base(connectionString)
{
Database.SetInitializer<SubDbContext>(new
CreateDatabaseIfNotExists<SubDbContext>());
}
}
Connection strings:
<add name="DefaultConnection"
connectionString="Data Source=.\SQLExpress;Initial Catalog=master_db;Integrated Security=True"
providerName="System.Data.SqlClient" />
<add name="SubDatabaseConnection"
connectionString="Data Source=.\SQLExpress;Initial Catalog={0};Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
I am using {0} for formatting purposes. How can I enable migrations and apply changes to existing databases?
Modifications: I am linking tables to database in Register action like this:
SubDbContext newContext = new SubDbContext(string.Format(userDatabase, "sub_db_" + userId));
newContext.Countries.FirstOrDefault();
newContext.Cities.FirstOrDefault();
Your DbContext for all your sub-databases is SubDbContext. So you must enable migration based on one of them. then put this code as Configuration class:
internal sealed class Configuration : DbMigrationsConfiguration<SubDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
}
and put this code into the SubDbContext constructor:
Database.SetInitializer<SubDbContext>(new MigrateDatabaseToLatestVersion<SubDbContext, Configuration>());
it means, every database when found a new manual added Migration,
then try to migrate it.
and also you can use this approache too:
write this code in the Application_Start:
var context = new SubDbContext("your generated connection string");
var initializeMigrations = new MigrateDatabaseToLatestVersion<SubDbContext, Configuration>();
initializeMigrations.InitializeDatabase(context);
I hope you find it helpful.
For some reason I have a database with three types of tables with the same name but the prefix is different. The schema of database is this:
I must implement only the dbo.SpRicezioneSpedizioniLight tables manually and I have realized there are these two classes:
public class SpRicezioneSpedizioniLight
{
public string AudOperation { get; set; }
public Nullable<System.DateTime> AudDateLog { get; set; }
public int PROGRESSIVO { get; set; }
}
public class GemapDbContext : DbContext
{
public DbSet<SpRicezioneSpedizioniLight> SpRicezioneSpedizioniLights { get; set; }
}
How can I identify the specific table dbo.SpRicezioneSpedizioniLight? For now my connection string is:
<add name="SABIntegrationEntities" connectionString="metadata=res://*/Models.ModelTest.csdl|res://*/Models.ModelTest.ssdl|res://*/Models.ModelTest.msl;provider=System.Data.SqlClient;provider connection string="data source=localhost;initial catalog=SABIntegration;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework"" providerName="System.Data.EntityClient" /></connectionStrings>
All of this works fine in a local database with a single table.
Thank you
The "prefix" of your tablename is the name of the schema this table is associated with. "dbo" is the default schema name used by EF.
You can change the default schema by using
modelBuilder.HasDefaultSchema(SchemaName);
in your OnModelCreating-Method or map your other type to the type explicitly using
modelBuilder.Entity().ToTable("SpRicezioneSpedizioniLight", "bak");
I'm trying to learn EF 6 Code-first in WPF by following some tutorials. Since I'm familiar with model-first I can understand most parts except I've found ContextInitializer a little confusing. I defined a ContextInitializer like this code:
public class ContextInitializer : DropCreateDatabaseIfModelChanges<Context>
{
protected override void Seed(Context context)
{
var customers = new List<Customer>
{
new Customer{Name="Jane",Phone="2238718"},
new Customer{Name="David",Phone="43245608"},
new Customer{Name="Mike",Phone="90814417"}
};
customers.ForEach(cu => context.Customers.Add(cu));
context.SaveChanges();
}
}
and this is my Context class:
public class Context : DbContext
{
public Context()
: base("MVVM")
{
}
public DbSet<Customer> Customers { get; set; }
}
and It created a database at first run which I think it's weird because this class has zero refrences. Since Seed method doesn't fire again, I can't understand how this works.
Can someone explain to me how my ContextInitializer with zero reference created a database?
Does the following section exist in your App.Config?
<contexts>
<context type="(your name space).Context, MVVM">
<databaseInitializer type="(your name space).ContextInitializer, MVVM" />
</context>
</contexts>
If it is, the program knows where to look to find the ContextInitializer. If the database already exists and the tables in the database already match those of the POCO/model classes, nothing happens. If the model has changed or the database doesn’t exist, this class will be invoked, resulting in the database being seeded with your data.
I get this error when I attempt to save to the database.
In the Controller I have the Edit HttpPut
public ActionResult EditSubject(Models.xxxx model)
{
//Database Model Class
SubjectDB subjectdb = new SubjectDB();
// Name of DB Access in Web.config
BeaconDBEntities db = new BeaconDBEntities();
if (ModelState.IsValid)
{
subjectdb.SubjectId = model.SubjectId;
db.SubjectDBs.Add(subjectdb); --> Pops InvalidOperationsException
db.SaveChanges();
}
In Models folder is the model for the database table
SubjectDB.cs
namespace xxx.Models
{
public class SubjectDB
{
public string SubjectId { get; set;}
}
public class BeaconDBEntities: DbContext
{
public DbSet<SubjectDB> SubjectDBs { get; set; }
}
}
Web.config is the connect string for the database
<coneectionStrings>
<add name="BeaconDBEntities" ...............
</connectionStrings>
The first thing I see is that your connection string name 'BeaconDBEntites' does not match your DbContext inherited class name 'BeaconDBEntities' (you are missing an 'i' in the word Entities). Try changing that and see if it fixes it.
When you edit your data then i think you don't need to write code like this when your useing entity framework it's below code
db.SubjecDBs.Add(subjectdb);
db.SaveChanges();
first when you update your data then first your get your data with your id like this it's below
and your create object your entity class. your entity class is your table like below
SubjecDBs objsub=new SubjecDBs();
var data =db.db.SubjecDBs.where(x=>x.SubjectID==ID).ToList();
then you match your data which is you wont to update like below
objsub.SubjecName=data[0].SubjecName
and you match your field which you wont to update then your write below code like this
db.SaveChanges();
i think this will help you...