My Website has two databases, one for user accounts and one for content. Both are created code first, and both have data in them.
But I have only one mdf file in the project. The site works locally, the content gets displayed, I can edit and add to it, and the changes are effective. I can add users, and their accounts work. But the only mdf file I have in the project is the user database.
I can connect to localdb in sql server managment studio and get only the user database. There's no database whose structure and tables would match the content database. I can go to server explorer in Visual Studio, and only the user database shows up under connections. I did of course refresh my solution explorer several times with "show all files" on. I even did a full disk search for all mdf files anywhere on my computer, and it didn't come up with one that would fit the bill.
I tried to fiddle with connection strings in web.config (of which there were none auto-generated) because I read that this could trigger the creation of the mdf file (although the context was always an empty database that didn't get created), but all that brought me was that the application now didn't find the database anymore either. reverting the changes in web.config did not resolve that issue, but reverting the whole project from svn did.
The database was migrated 10 times during development, always without error. Everything works fine, except I can't find the physical database anywhere. Which of course is a problem for deployment.
I had noticed that I had only one mdf file in the project during development, but I didn't think much about it at the time. after all, everything worked (and still does).
Are there other means than mdf by which ASP.NET MVC can store a database? That data I'm seeing on the screen has to come from somewhere... but for all I can tell, not from an mdf file.
EDIT: after reverting and rebuilding, there was now a default connection string generated in web.config. However, it simply points to the user database, i.e. the file I can find in the App-Data folder:
connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-RAOC-20150430022043.mdf;Initial Catalog=aspnet-RAOC-20150430022043;Integrated Security=True" providerName="System.Data.SqlClient"
-----some more info-----
I have experimented with connection strings some more. On adding the following connection string to web.config, the .mdf file finally got created:
<add name="RAOCentities" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\raoc.mdf;Initial Catalog=aspnet-raoc;Integrated Security=True" providerName="System.Data.SqlClient" />
However, as was kind of expected, it didn't contain the content, so I got a null reference exception. Removing the connection string from web.config restored the old functionality. So the real question it comes down to is: Where is that content stored? and how can I put it into an mdf?
-----still more info-------
After some experiments, the conclusion that the content data is indeed stored inside the user database seems inevitable. At least that seems to be the only file that changes if I change the content according to an svn dif. But I can't see the tables in sql server managment studio. I can only see the tables from the user database (your default applicationdbcontext), not from my own entities. Yet everything points to the fact that the data is in there somewhere. Anybody got any ideas how that is possible?
Well, I'm still in the dark on what went on and how those two databases could exist in the same file with SQL-server manager only seeing one of them but ASP.NET obviously being able to access both, but at least I solved the problem.
On the off-chance that anyone should ever find himself confronted with the same problem, here's what I did:
I duplicated the database model under another classname and set a connection string to it. Doing this resulted in the output of an empty database with the right tables as an mdf file, while not breaking the connection to the unfindable database with the actual data in it. Then I ran a short function that copied the contents of the filled database into the empty one, removed the duplicated class and set the connection string to connect the now populated mdf with the original database model. Result: a working database I could actually publish.
Connect to LocalDB in SSMS
Open Server Properties -> Database Settings
Change Data/Log/Backup locations -> click OK
When I click OK I get this error:
Found some blogpost and changed this in regedit but it didn't help.
Anyone got any other ideas I could try?
I do not believe that these default paths for SQL Server LocalDB are changeable. This is quite unfortunate due to what appears to be a bug with SQL Server Express 2017 LocalDB ** (fixed as of CU 6 for SQL Server 2017), as per this question (and my answer to it) on DBA.StackExchange:
LocalDB v14 creates wrong path for mdf files
HOWEVER, you do not need to use the default paths. Those are used when you create a Database without specifying the physical locations. If you specify the physical location, then you should be able to create the files to any folder / directory that you have read / write access to.
After making that change in the registry try restarting the sql instance.
Also I would make sure that the account running SQL Server has the ability to write to that folder.
for an easy test you could go to the folder properties -> security then add the account 'everyone' then give them full control. then try making that change. If it works it was a permissions issue to that account. Accounts generally don't have access to other users accounts without some level of admin.
After 10 years this is still an issue for the current version(15.0) of Microsoft SQL Server Express.
After a bit of investigation I discovered, there is an issue with permission inside the registry. The process sqlservr.exe cannot create entries in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15E.LOCALDB\MSSQLServer.
On my computer this process is running under my account, so I opened regedit and gave myself Full Control permission to this key. And it worked like a charm. I hope this will help you as well.
Changing these paths in RegEdit or SSMS doesn't work, SQL LocalDb won't respect these values for existing databases. One has to move the databases manually. Here is the reliable way to change a database location for any LocalDB instance.
First, make sure you work with a correct instance of SQL Server LocalDB. In command prompt enter:
sqllocaldb info
It will show the LocalDB instances you have on your machine. Let's assume that the instance name is MSSQLLocalDB.
Next, execute this script on your database (let's call it TestApp), using SqlCmd tool or SSMS:
alter database TestApp
modify file (name = TestApp, filename = 'C:\NewDataLocation\TestApp.mdf');
go
alter database TestApp
modify file (name = TestApp_log, filename = 'C:\NewDataLocation\TestApp_log.ldf');
go
Now, stop the SQL LocalDB instance, in command prompt:
sqllocaldb stop MSSQLLocalDB
Move the database files to the new location that you specified in the script. From %UserProfile%\TestApp.mdf (which is where they are located) to C:\NewDataLocation\TestApp.mdf, same for LDF file.
Start the SQL LocalDB instance again:
sqllocaldb start MSSQLLocalDB
Now your database is working from a new location. Repeat the steps for any other databases.
Paths Cannot Be Changed in SQL Server LocalDB "Automatic Instance" Types
In case anyone in 2023 finds out they cannot change their default database file storage paths, this article is for you!
This error applies to Microsoft SQL Server not being able to allow you to change the default file folder location on your PC where the SQL Server Database Files are saved (database and logs files, .mdf and .ldf).
Most developers often need control over where local database files are saved. Most prefer to store them in a central location, another drive, or simply the main SQL Server database repository inside the C:\Program Files\Microsoft SQL Server\{sql version name}\MSSQL\DATA, since that is where system data storage goes. One example of the problem of not being able to customize database file storage might be using Entity Framework Core, which runs "migration" scripts that create databases in SQL Server. When it does so, where those scripted databases get stored is heavily dependent on SQL Server's default file path settings. When the location of those EF code-first database files using LocalDB is locked down, developers are stuck with SQL files in multiple locations on their PC's.
THE PROBLEM
Apparently, when Microsoft installs SQL Server / SQL Express on your device, it attempts to install a default instance of the server as a specialized type called a "LocalDB Automatic Instance". They do this to get the user up and running fast with a "LocalDB" sql server instance, which is a one-time, "light", custom created server running as a public instance, complete with default settings which are customized for the user (or developer) so he can get up and running fast. The automatic type has the advantage that its granted permissions to the user as administrator in SQL, as well as granting all applications on the user's device public access to the server instance. (You will notice that IIsExpress works this way using ApplicationPools as dummy Windows User Accounts, creating default accounts next to your User Account in Windows to run app pools in IIS.) These SQL Server LocalDB binaries do not run as a service but on-demand. But only one of the "automatic" types may be installed per version per device. The other SQL Server LocalDB type is the named instance and is not as restricted as the automatic one, apparently.
The problem is, when they create this special LocalDB automatic instance, it locks down certain settings and applies certain permissions and settings that are unique just for this instance. This then limits what the user can do as far as customizations, one of which is the "Database default locations" in the Properties dialog box that appears when you right-click your sql server instance and choose properties.
Anyone using the full SQL Server version, or who has created a new instance of LocalDB, deleting the old one, will not experience this issue, so most of those people are scratching their heads.
But for local developers, what this means is your Sql Server LocalDB databases running under this instance of the server will typically store their databases under a locked down path...either the path you chose on install or default to the user-friendly account paths under C:\Users\{YourName}.
When users attempt to change the path in the properties box for the instance, many users online the past 5-6 years have noticed a nasty RegCreateKeyEx() returned error 5 Access is denied that would appear when saving a default path. Microsoft doesn't bother to tell you, but that is intentional. They don't expect to allow you to save paths to the registry for the instance, and assume everyone is ok with the default path.
You can fix the key error by going into your registry and changing permission on the Microsoft SQL Server registry keys, assigning the "Everyone" group account to the registry node managing these keys. In the Registry, add Everyone group account to this node below then try and save a new default path in the properties box for your sql server localdb instance:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server
The location of the default database file path keys (2019) in the Registry in Windows for an instance of the localdb server of are located here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL15E.LOCALDB\MSSQLServer
You are then able to save the new default paths in SQL, and the error goes away. Saving your default path in the Properties box works now, and the new values appear in the registry.
Even though you can change these paths, they will not stick, however, and reset back to the User Account Path, by default. Even if you save a new default sql path for your databases, when you create a new database it still reverts to the old path. Again, this applies ONLY for users who are running under the default "Automatic" LocalDB instance created on install of SQL Express.
So even after restarting SQL, restarting your PC, or restarting the SQL Service, those registry values will still not pull the registry keys into the SQL Server instance settings for Default file paths.
As proof, run these two scripts below in your SQL Server LocalDB instance. The first one returns the actual LocalDB default file paths SQL Server stores internally. The second script returns what is stored in your registry for the LocalDB default file path. If you saved new default path registry keys, they should be the same and shown in SQL Server instance properties, but they are different! That means Microsoft has decided not to allow you to change them for those running the "automatic" instance type of LocalDB on install. Below is the T-SQL to run to test this:
-- GETS THE PATH STORED IN SQL SERVER FOR "DefaultData" path
SELECT
[Value] = 'DefaultData',
[Data] = SERVERPROPERTY('InstanceDefaultDataPath')
-- DefaultData C:\Users\YourAccountName\
-- GETS WHATS IN THE REGISTRY FOR "DefaultData" path
EXECUTE [master].dbo.xp_instance_regread
N'HKEY_LOCAL_MACHINE',
N'SOFTWARE\Microsoft\Microsoft SQL Server\MSSQLServer',
N'DefaultData'
-- DefaultData C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA
-- Note: If the second one returns `NULL` it just means you
-- have not yet tried or succeeded in saving a new file path
-- to your registry.
Why isnt SQL Server LocalDB pulling in the registry values?
What this means again, is sorry you can't change these default paths. Your best bet is to simple "detach" your databases, copy the .mdf and .ldf files to your new prefered folder, then reattach. When you create new databases, the console allows you to change the database file path there, as well. There are also some elaborate SQL scripts you can run to set paths before saving files.
But just know this is by design.
I think one of the purposes of LocalDB is that it is very convinient in bundling a demo database along with the source files of an application. The database file and its log, of course, are somewhere in the source file directory.
Take a Visual Studio solution for example, in web.config or app.config, you can see something like this:
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-XXXXXX-20140609153630;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-XXXXXX-20140609153630.mdf" providerName="System.Data.SqlClient" />
Now that the location of every LocalDB is specified in the config file, I don't think "default location" makes much sense.
I use a .mdf file as my database. I also used Linq-to-SQL connection.
At first, my application can add and display the data in the .mdf file correctly. But when I try to see the data by clicking the .mdf file directly and from the table, the database is empty.
I've set the .mdf file and the .dbml file Copy if newer, but still nothing.
Please help me and thank you for your help.
I bet your connection string contains
AttachDbFileName=somefilename.mdf
The whole User Instance and AttachDbFileName= approach is flawed - at best! Visual Studio will be copying around the .mdf file and most likely, your INSERT works just fine - but you're just looking at the wrong .mdf file in the end!
If you want to stick with this approach, then try putting a breakpoint on the myConnection.Close() call - and then inspect the .mdf file with SQL Server Mgmt Studio Express - I'm almost certain your data is there.
The real solution in my opinion would be to
install SQL Server Express (and you've already done that anyway)
install SQL Server Management Studio Express
create your database in SSMS Express, give it a logical name (e.g. YourDatabase)
connect to it using its logical database name (given when you create it on the server) - and don't mess around with physical database files and user instances. In that case, your connection string would be something like:
Data Source=.\\SQLEXPRESS;Database=YourDatabase;Integrated Security=True
and everything else is exactly the same as before...
I have an ASP.NET MVC solution with a DB named LearningDB.
Here is my connectionstring in my web.config
<add name="EntityFrameworkDbContext"
connectionString="Data Source=.\SQL2008;Integrated Security=SSPI;Initial Catalog=LearningDB;MultipleActiveResultSets=True;User Instance=true"
providerName="System.Data.SqlClient"/>
My Sql Server is named SQL2008 and is a full SQL SERVER (not the express one).
Strange thing: when I run my solution, it successfully created the DB and allows me to add data to this DB. I didn't use the AttachDBFilename attribute (to specify where to store the DB) so the DB is located under C:\Users\Thierry\AppData\Local\Microsoft\Microsoft SQL Server Data\SQL2008
I already query the sys.databases to list my table but I only have 4 tables (master, tempdb, model, msdb). I would like to delete these corrupted references to deleted databases but I don't know where!
Any idea?
Thanks.
EDIT
As Mikael suggest me, I edit my question to be clear: I didn't want to delete master tables, etc...
Le'ts take an example: I have a DB named LearningDB.mdf in my asp.net mvc solution. I deleted physically this DB (with Windows Explorer, I know this is not the best thing to do). Next, when I restart my solution and run it, the system try to recreate the DB and warn me that the name LearningDB is already exist!! How this can be?? I already check in SQL SERVER with Management Studio but didn't found anything!
I'm learning ASP.NET MVC 3 with Entity Framework Code First. I'm following a tutorial and I downloaded the corresponding solution for testing on my local machine. Now, something I didn't understand very well is about the automatic creation of the database (if this one didn't exist yet on disk). The very first time I run the application, the database is created for me. That's ok.
Here is the section in Web.config
<add name="BlogContext"
connectionString="Data Source=.\SQL2008;Initial Catalog=CodeFirstMVC.mdf;Integrated Security=SSPI"
providerName="System.Data.SqlClient" />
But I have two problems:
1st. For testing purpose, I deleted the database on disk and run again the solution. I thought that the database would be automatically created but I was wrong: I got the error message below:
{"Unable to open the physical file \"c:\\Program Files\\Microsoft SQL Server\\MSSQL10.SQL2008\\MSSQL\\DATA\\CodeFirstMVC.mdf.mdf\". Operating system error 2: \"2(failed to retrieve text for this error. Reason: 15105)\".\r\nCannot open database \"CodeFirstMVC.mdf\" requested by the login. The login failed.\r\nLogin failed for user 'sa'.\r\nFile activation failure. The physical file name \"c:\\Program Files\\Microsoft SQL Server\\MSSQL10.SQL2008\\MSSQL\\DATA\\CodeFirstMVC.mdf_log.LDF\" may be incorrect."}
I noticed that if I changed the file name in my Web.config then the database is again successfully created. Can you explain me? Why do I have to change the database name to get it running again?
2nd. The database is created in the folder located in C:\Program Files\Microsoft SQL Server\MSSQL10.SQL2008\MSSQL\DATA. I would like to store my database in the App_Data directory. How can I proceed?
Initial catalog is not path to file. It is the name of database. AttachDbFilename is used to specify the file so your connection string should look like:
Data Source=.\SQL2008;Initial Catalog=CodeFirstMVC;AttachDbFilename=|DataDirectory|CodeFirstMVC.mdf;Integrated Security=SSPI
Where |DataDirectory| instructs SQL server to use local application data directory instead of global SQL Server data directory. Local data directory for web application is App_Data.
Edit:
I just noticed that you are probably using full SQL server instead of SQL server express. As I know creating database in App_Data automatically is feature of SQL server express. That also explains first error because SQL server created database called CodeFirstMVC.mdf and stored the database in its global data directory within CodeFirstMVC.mdf.mdf file and transaction log in CodeFirstMVC.mdf.ldf file. It also registered that database internally. By deleting files you didn't remove database from SQL server. You just break its functionality but SQL server still believes that the database exists. That is also reason why you have to change the name to make it work.