I want to make Entity Framework showing me message : 'There is no database' (if database not exist) and asking me for create db or not;
i use CodeFirst.
In your 'DbMigrationsConfiguration' class, you should turn off any automatic migrations:
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
Now on bootup, it won't do anything other than throw an DBMigrationException when you first access the database. So, before you access the database, check to see if it exists by using the following:
dbContext.Database.Exists();
You can then ask your questions about server location, etc, followed by creating the database with:
var migrator = new DbMigrator(new Configuration());
migrator.Update();
This isn't something built into Entity Framework, nor does it make sense to build it into Entity Framework, because it is so specific to your particular application that whatever you come up with won't be directly usable in any other application.
You can simply configure EF to not automatically create any database. If connecting to the database fails, check if you can connect to the server. If you can connect to the server, check if the database exists. If the database does not exist, offer to create it.
Related
I have a c# .NET application with a SQLLocalDB database. I have used database first to create the EF6 model. I have added columns to one of the tables using SQL Server Management Studio and then used 'Update model from database' to propagate the changes into my model. When doing this, data on the development PC is unaffected and incorporates the new columns. However, when a different user runs the new version of the application, their existing datafile (.mdf) won't recognise the new columns and crashes with the exception:
System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Invalid column name 'VAT_long_description'
making the user's existing data in that table unreachable. I appreciate that Code First gives the ability to migrate data, but this facility appears not to be available when building the EF model using database first.
My connectionString is:
<add name="PMMEntities" connectionString="metadata=res://*/PMMData.csdl|res://*/PMMData.ssdl|res://*/PMMData.msl;provider=System.Data.SqlClient;provider connection string="data source=(localdb)\v11.0; AttachDBFilename=|DataDirectory|\PMM.mdf; initial catalog=PMM;Integrated security=True;MultipleActiveResultSets=True; App=EntityFramework""providerName="System.Data.EntityClient" />
I want to ensure that when a user installs a new version, their .mdf datafile will adapt to the new database schema without loss of data. It seems the only way to do this is through running a conversion or migration method on startup if the app throws the “Invalid column name” SQL exception. Where can I find the code (or a NuGet package) that will do this?
if you are using MVC , you have two methods to make an update in your models class database. the most easy way to resolve that issue is that you delete the model class related to the database and you import it again into your model folder. don't worry about data, they will still stored in your database. unless you have wrotten some extra object in the model class database, in this case you will waste those extra objects.. it will not affect your storage.
I have used the built in Database that comes with Visual studio by using Code First with Entity Framework. Now I wanted to move to an external database so I created one and saved the connections string. So I connected to my azure database by supplying the connection string in the db context constructor. Now though, the problem is that Entity Framework isn't able to create the necessary tables. When I run my application and try to access something, I get System.Data.SqlClient.SqlException: 'Either the parameter #objname is ambiguous or the claimed #objtype (COLUMN) is wrong.'
And I assume this is beacuse my azure db is empty. Why doesn't Entity Framework create the tables?
The error was that I had forgotten to run migration on the new database:
*Add-Migration newDb
*Update-Database
I have a database where I created a contained user and I needed to connect to my web app using that user. I have always been able to connect to the web app with a standard user having Persist Security Info=False.
However, the only way I was able to connect with the contained user was changing my connection string to Persist Security Info=True, otherwise I'd get a login failed sql exception even though I was able to connect using SSMS. I'm not sure why it worked, does anybody know why a contained user needs the property set to True?
For you web app, are you using Entity Framework ?
And for your DbContext are you using IdentityDbContext ?
If so, I had the same problem. I was able to connect directly with SqlConnection but encountered an "Access Deny" error when connecting with Entity Framework.
When I gave enough permissions to my user, all queries were very slow.
When instantiating the Context (with IdentityDbContext) you should set the second parameter to false.
public AdeleDbContext(string connectionString) : base(connectionString, false)
{
}
The second parameter is throwIfV1Schema and when set to true (which is the default value), it will validate schema against the database by calling SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=#Table for many columns.
That was the reason why the connection was slow and user needed more permissions when connecting to DB with Entity Framework and IdentityDbContext.
Background info:
I am about to start a new project written in C# (vs2015) which will be using Entity Framework 6 within its DAL. One of the core requirements is that the system must be able to run against either SQL Server, Azure SQL server, MySQL or Oracle as chosen by the user simply changing the connection string in the web.config.
So prior to the project kick-off I am trying to get more familiar with Entity Framework as I have not used it outside of a few tutorials before.
I have written a small proof of concept app, the purpose of which is to determine how I can use EF to quickly swap a web api to use a different underlying DB. For the PoC I am using SQL Server express v12 and MySQL v5.6, C#, Entity Framework 6 via a code first approach.
I have hit a road block with my PoC, I am seeing different behaviour when running against MySQL compared to when I am running against SQL Server. I am using the following EF context:
<context type="POC.Core.Api.DataAccessLayer.SchoolContext, POC.Core.Api" disableDatabaseInitialization="false">
<databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[POC.Core.Api.DataAccessLayer.SchoolContext, POC.Core.Api], [POC.Core.Api.Migrations.Configuration, POC.Core.Api]], EntityFramework"></databaseInitializer>
</context>
I have two migration scripts, one which is the initial creation and another which just adds a property to an object.
I have some test data being created in the seed method in the configuration class which looks like this (:
public Configuration()
{
AutomaticMigrationsEnabled = true;
this.SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());
}
protected override void Seed(WeldOffice.Core.Api.DataAccessLayer.SchoolContext context)
{
var students = new List<Student>
{
new Student { FirstMidName = "Carson", LastName = "Alexander",
EnrollmentDate = DateTime.Parse("2010-09-01") },
...
};
Both my MySQL and SQL servers do not yet have the database present at all yet.
As I want the user to be able to specify the DB I am relying on in-code methods to create the DB structure etc.
Given this scenario, my understanding is that the following occurs when the db context is first hit when running the app:
Check for existence of the database - it is not present so it will be created.
Check if the initial creation script has been run - it has not so run it.
Check if the add property script has been run - it has not so run it.
Run the seed method to ensure data is present and correct.
In MySQL this all works as expected, the database is created, the tables set up and the data populated. The two migration scripts are listed in the migration table.
In SQL Server, steps 1,2,3 all work and the database is created and the tables set up. The two migration scripts are listed in the migration table. However, step 4 is not run, the Seed method is never hit and instead a AutomaticDataLossException exception is thrown.
If I set AutomaticMigrationDataLossAllowed = true then step 4 also works and everything is as expected. But, I would not really want to have AutomaticMigrationDataLossAllowed set to true and don't see why this is necessary in SQL server but not MySQL. Why is this the case? I feel I am missing something fundamental.
Please keep in mind this is just a proof on concept, in production there will be no seed data anyway, and I would rather a dba create the db via sql scripts etc.
I read this post about EF code first migration, but it uses 'Package Manager Console' which is not effective on shared hosting. I would like to know how you are deploying EF code first database changes on the production. Is it good to do database changes manually?
You don't need to use the Package Manager Console to do the migration. There is a database initializer that will do the trick for you called MigrateDatabaseToLatestVersion (which can be read about here). It will have you create a Configuration file that will contain any specific setting or seeding that you want the database to do upon any migration.
After you set that up all you need to do in your code is this:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext,Configuration>());
var db = new MyDbContext();
db.Database.Initialize(true);
This will automatically do the migration for you based on your code first settings.