10

Apparently, using AttachDbFilename and user instance in your connection string is a bad way to connect to a DB. I'm using SQL server express on my local machine and it all seems to work fine. But what's the proper way to connect to SQL server then?

Thanks for your explanation.

Charlieface
  • 52,284
  • 6
  • 19
  • 43
frenchie
  • 51,731
  • 109
  • 304
  • 510

2 Answers2

17

Using User Instance means that SQL Server is creating a special copy of that database file for use by your program. If you have two different programs using that same connection string, they get two entirely different copies of the database. This leads to a lot of confusion, as people will test updating data with their program, then connect to a different copy of their database in Management Studio, and complain that their update isn't working. This sends them through a flawed series of wild goose chase steps trying to troubleshoot the wrong problem.

This article goes into more depth about how to use this feature, but heed the very first note: the User Instance feature has been deprecated. In SQL Server 2012, the preferred alternatives are (in this order, IMHO):

  1. Create or attach your database to a real instance of SQL Server. Your connection string will then just need to specify the instance name, the database name, and credentials. There will be no mixup as Management Studio, Visual Studio and your program(s) will all be connecting to a single copy of the database.

  2. Use a container for local development. Here's a great starter video by Anna Hoffman and Anthony Nocentino, and I have some other resources here, here, and here. If you're on an M1 Mac, you won't be able to use a full-blown SQL Server instance, but you can use Azure SQL Edge if you can get by with most SQL Server functionality (the omissions are enumerated here).

  3. Use SqlLocalDb for local development. I believe I pointed you to this article yesterday: "Getting Started with SQL Server 2012 Express LocalDB."

  4. Use SQL Server Compact. I like this option the least because the functionality and syntax is not the same - so it's not necessarily going to provide you with all the functionality you're ultimately going to want to deploy. Compact Edition is also deprecated, so there's that.

Of course if you are using a version < SQL Server 2012, SqlLocalDb is not an option - so you should be creating a real database and using that consistently. I only mention the Compact option for completeness - I think that can be almost as bad an idea as using AttachDbFileName.

EDIT: I've blogged about this here:

Aaron Bertrand
  • 272,866
  • 37
  • 466
  • 490
  • ah ok, now I get it: I removed the UserInstance=true parameter from the connection string and it seems to work fine. And what about the AttachDbFileName parameter? What's the danger with that one? – frenchie Jun 24 '12 at 16:51
  • Why would you only want to attach the database while your program is using it? If you attach the database *to your SQL Server* then you can access it through Management Studio or other programs at any time. What are you gaining by only attaching it at runtime while you're actively developing? If it's about resource usage, you can manually stop the SQL Server service. – Aaron Bertrand Jun 24 '12 at 16:56
  • I wasn't sure what the command was doing. Right now, I have this: Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\MySiteDB.mdf . How should I rewrite it so that I avoid doing the attachment to the runtime and instead go straight to SQL server? I attached the DB file to the SQL server by attaching it in Management studio. Is this good? – frenchie Jun 24 '12 at 17:05
  • 2
    Change `AttachDbFileName=[...].mdf` to `Initial Catalog=MySite` (assuming you gave your database the logical name `MySite`). – Aaron Bertrand Jun 24 '12 at 17:09
-2

In case someone had the problem.

When attaching the database with a connection string containing AttachDBFile with SQLEXPRESS, I noticed this connection was exclusive to the ASP.NET application that was using the database. The connection did block the access to all other processes on the file level when made with System.Data.SqlClient as provider.

In order to assure the connection to be shareable with other processes instead use DataBase to specify the database name in your connection string Example or connection string :

Data Source=.\SQLEXPRESS;DataBase=PlaCliGen;User ID=XXX;password=ZZZ; Connect Timeout=30 

,where PlaCliGen is the name (or logical name) by which SQLEXPRESS server knows the database.

By connecting to the data base with AttachDBFile giving the path to the .mdf file (namely : replacing DataBase = PlacliGen by AttachDBFile = c:\vs\placligen\app_data\placligen.mdf) the File was connected exclusively and no other process could connect to the database.

Eray Balkanli
  • 7,752
  • 11
  • 48
  • 82
marcob
  • 1
  • 1