How to work with LocalDB and EF, without using migrations - ef-code-first

I am on VS 2012 RTM, with EF 5. I am doing Code First, but trying to ignore Code Migrations since I am just in development. To avoid them, I have this set
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<SomeContext>());
Occasionally, even when I don't think I've touched the model, it decides to recreate. That's fine. But it usually results in the error
Cannot drop database because it is currently in use.
So I decided to delete the database entirely. I go into VS, go to the "SQL Server Object Explorer", find the DB and delete it. Now I'm stuck at
Cannot attach the file '{0}' as database '{1}'
I had this happen last night and I just fiddled around until it work (shut down tasks, restart VS, changed the DB and file names in the web.config, etc.
So question 1) How do I get out of this state?
But the more important question, how do I prevent myself from getting in this state at all?

The SQL Server Object Explorer window can hold a connection to the database. Closing the window and all windows opened from it releases the connection.

I had the same problem and managed to fix it. The main problem is that EF won't automatically create the database. The solution is not very hard.
First, go to the Solution Explorer and manually create the database. To do this, go to the folder where your database is located (usually App_Data). Right-click on this folder and click on Add -> New Item. Select the Data tab and select SQL Server Database. Make sure you enter the name Entity Framework expects (which is specified in the Cannot attach the file '{0}' as database '{1}' error message).
Then most likely you will get an error message that says that the database does not contain any model metadata. To circumvent this, change your database initialisation to:
Database.SetInitializer(new DropCreateDatabaseAlways<SomeContext>());
Now run the application and the database should be there with tables correctly created. Once this step has been successfully executed, you change change your database initializer back to:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<SomeContext>());

Related

Schema not updating when publish web app from Visual Studio

I am building an ASP.NET MVC EF app with code-first migrations and hosting it in Azure with Azure SQL DB. The first time I published this, it went fine. But since then my models changed, and my schema in the Azure DB is not getting updated to match. When I deploy, I do have "Execute Code First Migrations" checked. When that wouldn't work, I deleted my DB and then recreated it in the Azure portal, figuring that would trigger it getting updated. But then that didn't work, so I set AutomaticMigrationsEnabled = True in the migration Configuration. It is STILL not working, so currently my DB in Azure has none of my tables. HOW can I get the DB in Azure to be forced to update to match my models so the published site will work?? I did try looking for if there's a way to script the VS local DB to a Create query and execute that in SQL management studio, but couldn't find how to do that.
If you have made sure that you have selected update database in the publish setting, and the connection string is correctc and its still not updating. Maybe the following will help for you:
I sometimes get an issue like this, it is quite frustrating, My publish file is correct and my settings are set to allow SQL updates to occur during publishing. But sometimes the database hasn't been updated and I get a nice "backing context has changed" error, sometimes the culprit is the migration table that hasn't been updated. Unfortunately the only sure way to get your databases in sync is to check what migration history they are both at, by comparing [dbo].[__MigrationHistory]
If your published server is missing the latest migration history, then you can generate an SQL script of that by typing into the package manager console:
Update-Database -Script -TargetMigration [migration name]
'migration name' should be the name of the last migration that your published server had, visual studio will generate sql script that can be used to bring the database up to the latest migration from that target migration.
Sometimes (though very rarely, its only happened once or twice for me) the above doesn't work for whatever reason (usually because migration files have been deleted), if that is the case then its a good idea to script the whole database, and cherry pick the sql you need from that.
Update-Database -Script -SourceMigration:0
This will generate a script for every migration, you can then cherry pick based on the changes you've made. The 'latest' changes will be closer to the bottom of the file. every migrational change will start with an if check:
IF #CurrentMigration < '201710160826338_mymigration'
BEGIN
You can use this to pick the bits that you need, if you do pick the SQL be sure to include the update to the migration history. It will be at the end of the if block and look something like this:
INSERT [dbo].[__MigrationHistory]([MigrationId], [ContextKey], [Model], [ProductVersion])
VALUES (N'201710101645265_test', N'API.Core.Configuration', 'Some long checksum')
Including the migration history will ensure that visual studio doesn't have the problem again.
Hope this helps.

Cannot fill azure db with data. WebPage is connected to database but don't want to create tables

I created website using asp.net MVC with Entity Framework Code First. It worked before on Windows Azure, the site was available publicly.
For some reason, I deleted database that was used to store data of my webpage. I created new one, similar to previous one.
I properly connected my site to database (in solution I clicked "Publish", in "Settings" there is place to type data about database, in "Destination Connection String" window I typed all needed data and clicked "Test Connection" - everything seems to be fine)
I published my site, the site works correctly, but when I go to page that gets data from database is see this error:
Invalid object name 'dbo.AspNetUsers'.
In Visual Studio in "SQL Server Explorer" I can see what is in my database. In fact, there is nothing inside (there is one table: "__MigrationHistory" and as I suspect this is created by default).
How can I generate all those tables again? It should generate database structure automatically.
PS: Accidentally I deleted "migations" from my project, do you think this is the cause?
This is not my projects blame, it works OK on localhost on my computer, when I delete localDB, it generates new one without any problem.
Yes, you need migrations. But you can always re-create them (well, if you removed them all it will be initial migration containing all of your previous migrations).
To quick fix you can backup and restore you database on the server. And if you need to re-create migrations do the following:
Backup all your data
Delete the entire database (local and remote), delete all migrations from code.
Create databases (local and remote one).
Run "add-migration Initial" command from PM console
Run "update-database" from PM console.
Upload your code to the server again. If database is empty, new initial migration should be automatically applied.

ASP.NET MVC4 Code First - 'Cannot attach the file as database' exception

I'm using Code First concept in Entity Framework and I'm constantly getting the following exception while starting application:
Cannot attach the file 'C:\Users\Admin\Documents\Visual Studio 2012\
Projects\Pro\Pro.Web\App_Data\Pro.mdf' as database 'Pro'.
I've put this in Global.asax.cs but also without success:
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<ProWebContext>());
var ctx = new ProWebContext();
ctx.Database.Initialize(true);
I've checked under App_Data directory and there no database created. Also, under Server Explorer there is nothing under Data Connections. Everything was working fine yesterday and today not working at all. I've tried to connect to LocalDB with SQL Server Management studio but it says it cannot connect to local database. Any ideas what could be a problem?
Thanks!
I found the solution. With newest SQL Server Management studio there is no problem in connecting to the local database. Connection needs to be established like this:
After logging in we can still see old database present even if there is nothing under App_Data directory and under Data Connections in Server Explorer in Visual Studio. When we delete that database from SQL Server Management studio and start application again there will be no more errors while attaching database.
I was facing the same error when I saw this but I couldn't delete the database using SQL Server Management Studio so I remembered IDatabaseInitializer.
Setting a database initializer for my Code First context solved the issue. In my case adding an initializer to always drop the DB worked (I added the code in the static constructor of my context, most people add it in Global.asax):
static SomeDbContext()
{
System.Data.Entity.Database.SetInitializer(new DropCreateDatabaseAlways<SomeDbContext>());
}
There are other initializers of course.
I just got into the same problem, and yet the answers above helped, the solution was different.
In my case, I was reusing a project that has already created it´s database. And since the name in the config was the same, it was throwing the exception, missleading the real solution.
It worth checking the database is not created and is different than the ones you used before. Change the name and go ahead.
I deleted the mdf file manually so the code will recreate it again, and had the same problem. I solved it by running update-database command in the package manager console.

ADODB recordset error "Operation is not allowed when the object is open" (3705)

I have a legacy ASP application that I support. By support I mean that I haven't touched it since about 2005 because its just worked.
However there were a couple of data issues in the Access database that the ASP application uses. So like a fool I opened the database directly over a fileshare (using MS Access 2007), fixed the data and saved it down (in Access 2000 format).
Now the application will retrieve and display the data OK, but any updates fail with the error 3705: Operation is not allowed when the object is open. I have not changed the code in any way, the only change was the data update and database save.
I've found plenty of examples of this error, but they all relate to fairly simple issues like ensuring the recordset is closed before opening it, changing the CursorLocation enum, etc. I've tried most of these in the vain hope that something will work, but nothing has.
Any ideas how can I fix this?
Thanks.
UPDATE
I've installed a web based access database management system, and have tried to compact and repair the database. I received the error:
The Microsoft Jet database engine cannot open the file '<snip>'. It is
already opened exclusively by another user, or you need permission to view
its data. (-2147217911)
I have run the macro detailed here to determine who is logged onto the database, and just showed the admin user (which was me - while running it)
Those errors mean one thing: the database file is opened by some other process and thus is being locked.
Most likely that "web based access database management system" is the culprit, try to find how you can configure it to not lock the file, or get rid of it.
As a work around or way to verify the real problem, you can copy the .mdb file into different location and change the classic ASP connection string to check if you can update the database in its new location.
#Remou's comment above about checking the file and folder permissions was correct.
I had our server admin check the permissions, and it seems that the write access had dropped off the folder (and the files also inherit their permissions from the folder). He said that this has happened before when saving directly over the fileshare.
(accepting in lieu of an answer from #Remou)

SQL Express & IIS - A database won't attach if you manually detached it?

Since the answers did not really cover the problem, I posted this on ASP.Net and completly rephrased it. I will post the edited question here:
I have been using the attachDB connection string and I usually deploy to IIS. The site works fine, however, I made some changes to the database and the newest version would not copy as it said file in use.
I opened up SQL management studio and saw that it was mounted so I did a dettach.
I was then able to copy the new version without problem, however, when I next run the site, I get:
Unable to open the physical file "C:\inetpub\wwwroot\vs\App_Data\aspnetdb.mdf". Operating system error 5: "5(failed to retrieve text for this error. Reason: 15105)".
An attempt to attach an auto-named database for file C:\inetpub\wwwroot\vs\App_Data\aspnetdb.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share.
And, if I try to access .Net users or the other few options within IIS Manager, I get the following error:
.NET Users
There was an error while performing this operation.
Details:
A connection was successfully established with the server, but then an error occurred during the login process. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)
OK
I have tried recycling the application pool, restarting the SQL instance and even restarting the computer.
Nothing helps and I cannot figure out what is wrong... Where does it remember where previous databases are connected and why doesn't it automatically reattach the database?... Someone said that they auto detach after 2 1/2 hours, however I waited 5 hours when a database wasn't in use and SQL Manager showed it was still attached.
When I manually reattach the database, everything works fine.
When you ask a database to be attached on-the-fly to a SQL Express instance using the AttachDBFileName connections string the application will not connect to the SQL Expres sinstance at all, but instead it will connect to a child instance, which is an new instance created specificaly for the user requesting the attach operation. See SQL Server 2005 Express Edition User Instances. This child instance will attach the database and will continue to run for up two one hour, after which it will shut itself down.
When you try to connect from 'enterprise manager' you will not be able to connect to the child instance (is realy complicated to connect explicitly to one, so you cannot accidentaly do it), you are connecting to the parent instance and messing with the database.
To summarize, either stick with the RANU model and use AttachDBFileName, or use a normal database operations mode and manage the database from the SSMS. Don't mix the two.
Are you certain there isn't already a database with the same name attached to the SQL Express instance you are pointing your site at?
Also, does the identity the site is running under when it attempts to attach the database have admin rights in SQL Express? If not, this command won't work (I'm not sure what error it gives in that situation, but "Access Denied" would sound reasonable).
The page "SQL Server 2005 Express Edition User Instances" seems to give a good overview of the issues and workarounds.
Edit to add
Could this be the issue:
An error will be generated if a log file exists in the same directory as the data file and the 'database' keyword is used when attaching the primary data file. In this case, remove the log file. Once the database is attached, a new log file will be automatically generated based on the physical path.
Taken from the documentation for SqlConnectionStringBuilder.AttachDBFileName Property
You'll need to delete the log file before you can re-attach the database through this method.

Resources