Close database connection in MSSQL server - c#

I am writing integration tests to verify the behaviour in my repositories. The problem I run into is that I want to start with a clean database for every test. I managed to do so by writing the SetUp as follows:
[SetUp]
public void SetUp()
{
_applicationContext = new TestApplicationContext();
_applicationContext.Database.Connection.Close();
_applicationContext.Database.Delete();
_applicationContext.Database.Create();
_tenantRepository = new TenantRepository(_applicationContext);
_userRepository = new UserRepository(_applicationContext);
}
The TestApplicationContext sets the database name to TestDatabase.
This works fine until I want to check the actual database for the result of my test. Then I make a connection from MSSQL server to the same database, which won't close until I either:
shut down MSSQL server
delete the database with the option "close all connections"
The only way I found is via SQL commands. Maybe it's because of my n00b knowledge regarding MSSQL, but I was kinda hoping for a "close connection" button / option.
How can I close the connection to the database from MSSQL server?
Or, is there a way I can do this programmatically from C#?
UPDATE:
Maybe I wasn't very clear. But the test SetUp fails after I opened MSSQL and viewed the contents of a table. This is because MSSQL also creates a connection to the TestDatabase, and my integration test is not able to close that connection. So I am looking for a solution that allows me to close the connection I created from MSSQL server.

You can work around the connection problem if instead of dropping and re-creating whole database you just drop and re-create selected (or all tables).
You could create little script that will do it for you in a way that you do not need to hard-code table names:
http://www.apexure.com/blog/2010/07/29/delete-all-tables-in-sql-server-database/
Alternatively, Julia Lerman in her book "Programming Entity Framework: Code First" mentiones this approach in more mature form, as incorporated as a custom database initializer:
As well as writing your own custom initializers, you can also find
initializers that other people have created. One example of this is
available in the EFCodeFirst.CreateTablesOnly NuGet package. This
initializer will allow you to drop and create the tables in an
existing database, rather than dropping and creating the actual
database itself. This is particularly useful if you are targeting a
hosted database where you don’t have permission to drop or create the
entire database.

You're releasing the connection back to the connection pool, not actually closing it. Instead of creating/deleting the database for each test, begin new transaction in setup and rollback in cleanup. This way no changes will be committed to your database and your test will always start from a clean state.
Also, because you are testing against live database, I wouldn't call your tests "unit" tests. Unit tests do not have any external dependencies.

The only way to reliably get an exclusive lock on a database is to use the SINGLE_USER WITH ROLLBACK IMMEDIATE technique. I recommend that you create a database snapshot with an empty state and restore to that snapshot each time. That will be much faster.

Related

How can you create a test database in Visual Studio?

We have a project for school in which we have to create a web application. We have access to an online database, but the problem is that we have to connect through VPN before we can connect to it.
For this reason, we're looking for a possibility in which we have a local database (which would be in the project, I suppose?) that we can all use (the project is on a subversion server). But when we deploy the project on our deployment server, we want it to use the real database connection.
I think I've seen it before, but after searching for hours I couldn't find anything relevant.
Is this possible?
EDIT:
We use MVC5 with Entity Framework.
People typically do this in one of several ways depending on what you want to achieve.
Pull down the database as an mdf file and store it in your repository. You can then have a manual step during setup where you ask people to import it into their database (I recommend localdb for local development but sure, you can use sql server or something).
Advantages: Very simple to set up for the person arranging this.
Disadvantages: Manual step is difficult for beginners. If the database is large it will swell your repository. If one developer changes the database (for example by adding a column) then you have to let everyone know to blow away their copy and restore from backup. Also, there is no real explicit history of how your database changes and your test database is not integrated with whatever you have to do for deployment.
Pull down the database as an mdf file. Include this file in your project and set it's properties as Content/Copy if Newer. Then use it directly using a connection string to attachDb such as Server=(localdb)\v11.0;AttachDbFilename=.\MyDataFile.mdf;Database=dbname;.
Advantages: No manual step, everything just works
Disadvantages: Obviously you'd want to use relative paths for AttachDbFilename and I'm not 100% that this is supported. Also, same as above but instead of having to let everyone know when their db needs restoration it just restores behind the scenes. This can mean users suddenly see their data disappear with no notice. It can also fail sometimes due to things like a locked database file and everyone just has to get good at keeping an eye out for that.
Maintain a sql script that can recreate your database in localdb. Provide people with a powershell or batch script (also in source control) to run it easily. Optionally use a post-build script that determines if you need to recreate the database and runs it.
Advantages: Everything is very explicit. Reasonably small size in the repository (which should be able to store text efficiently). You can use the same script as part of deployment.
Disadvantages: More work to set up. Still no real way to deploy changes to existing databases.
Use Entity Framework Database first. I can't speak to what the process looks like exactly when doing this but I know that it is possible.
Advantages: I guess.
Disadvantages: Ewwww EF database first
Use Entity Framework Code First with Migrations. Use explicit migrations (not the silly auto-generate-my-entire-db cruft) and write a proper Seed method to populate your data.
Advantages: This is what professional developers do and is based on tested patterns used frequently by Rails, Django, and many other frameworks. It is very flexible and explicit and supports changing existing databases.
Disadvantages: Can be quite difficult to set up if you don't have experience and especially if you're unaware of the migrations pattern. There's some naming difficulties that make it kind of hard to google (database first EF vs code-first EF, explicit migrations vs auto-generate-the-db, several different Seed methods that depend on your initializer).
You can create a local database using Entity Framework, which saves the database file on the local filesystem, which you can push to your version control server to share with your colleagues. If you decide to deploy the database, you can generate an sql script that you can run on the production database. You can do so by connecting to the local database using SQL Management Studio. You will just need to modify the connection string of the published application after deployment.
You used to be able to use Sql Server Express but it has changed to LocalDB and can be installed and run locally.
http://blogs.msdn.com/b/sqlexpress/archive/2011/07/12/introducing-localdb-a-better-sql-express.aspx
https://msdn.microsoft.com/en-us/library/ms233763.aspx

Thread Safe way to access SQL CE Database

Background:
In my windows phone project. I use local SQL CE database to store date. The create the database tables using LINQ to SQL programmatically.
This database is accessed through various datacontext instances in couple of threads.
Here's the issue:
I give an option to the user of my app to erase all the data and logout. When the user selects this, I delete the database using the datacontext's DeleteDatabase method. But, I always receive the error that the database is being used by another process, hence cannot delete.
Any nudges in the right direction will make my day.
Andy as mentioned above (to be honest they beat me) the problem was accessing the database when another process still had the connection opened. Basically it can be easily fixed by placing any code you run against the database inside of a using block like so:
using (MyDataContext db = new MyDataContext("isostore:/MyData.sdf"))
{
//Run database logic here
}
I guess in a sense it makes perfect sense for the error. Same thing happens with open files in WP7.
For more information and an example check out this page.

Synchronize a client database with the central database

I need to update existing data or insert new data from client database say DB1 into central database say DB2 both holding same schema and both databases reside in same machine. The updates are not biderectional. I just want changes to be reflected from client(DB1) to server(DB2).
The client database(DB1) is nothing but the backup database(Full database backup consisting of mdf and ldf files) which is attached to the same server where the central database(DB2) exists. I am not going to make any changes to the backup database(DB1) once it is attached to the server. The backup database(DB1) already has the modified data which i want to update it to central database(DB2) . So how do i do programatically using C# .NET?.Can you give any example code?
I have tried transactional replication with push subscription without sending the snapshot. The problem is that the i want to update the modified data from DB1 to central database DB2 at the first shot itself but transactional replication will not allow me to do so. It will not send any modified data which is already present in DB1. So the initial data present in DB1 is untouched when you try to send without snapshot. The backup database (DB1) already has the modified data prior to replication. How do i tackle this as i am not going to insert any new or modify data into the backup database(DB1) after i set replication.
Thanks and regards,
Pavan
Microsoft Sync framework is the best solution, especially if you are using express editions (in which case replication will not work).
Sync framework is quite straight-forward if used with SQL server change tracking in sql server 2008. You can define your mode of synchronization as well (bi-directional, upload only, download only) and also define what happens when there are conflicts (for instance constraints get violated, etc).
And yeah - just google for an example there are several straight forward walk throughs available on the topic, including peer-peer synchronization (might be the one you require) and client-server synchronization (client should be sql server compact edition).
You may also want to explore SQL Server's merge replication functionality. It is the replication type designed to allow satellite databases to automatically post back their results to a central repository.
To achieve this you have the following options:
1.) Use SQL Server Transactional Replication. Make DB1 as Publisher, DB2 as Subscriber and go for Pull or Push based subscription. All changes in DB1 will be simply reflected to central. If any changes we there in Central for the same tuple, they will be overwritten by DB1 changes.
Advantages: Easy to implement and reliable
Disadvantages: Very little customization
2.) Use Microsoft Sync Framework SQLDataBaseProvider.
Advantages: Very Flexible
Disadvantages: I have heard bad things about it but never tried.
3.) Custom Implementation: This is a bit hard as you need to track changes on DB1. One option can be reading transactional logs which Transactional Replication does internally or other option is to use trigger and build knowledge of changes. Then you need to write a library or routine which will get you change knowledge then it will apply to central.
Edit:
For backup and restore database progmatically:
http://www.mssqltips.com/tip.asp?tip=1849

How to install and setup a database with .NET?

I am currently working on a project that include the use of SQLServer. I would like to know what strategy I should use when I install the software to build the database? I need to set up the tables, the stored procedures and the users.
Does my software need to make a check on start up to see if the database exist and then if it doesn't, create it up?
Is there any way that I could automate this when I install SQLServer?
Thank you.
EDIT
Ok right now I have plenty of nice solution, but I am really looking for a solution (free or open source would be awesome) that would allow me to deploy a new application that needs SQLServer to be freshly installed and setuped to the needs of the software.
RedGate software offers SQL Packager which gives you option to produce a script/.exe to deploy whole db including everything (stored procedures, tables etc) from one single .exe. If you can afford it and want to have easy way to do it (without having to do it yourself) it's the way to go ;-)
Easy roll-out of database updates across your client base
Script and compress your schema and data accurately and quickly
Package any pre-existing SQL script as a .exe, or launch as a C# project
Simplify deployments and updates for SQL Server 2000, 2005 and 2008
You could use migration framework like Migrator.Net, then you could run the migrations every time your application starts. The good thing about this approach is that you can update your database when you release a new version of your software.
Go take a look at their Getting started page. This might clear up the concept.
I have succesfully used this approach to solve the problem you are confronted with.
You do all of that with the SQL scripts. And then your installation program runs them against the customer's SQL Server.
You can write a T-SQL script that only creates objects when they do not exist. For a database:
if db_id('dbname') is null
create database dbname
For a stored procedure (see MSDN for a list of object types):
if object_id('spname', 'P') is null
exec ('create procedure dbo.spname as select 1')
go
alter procedure dbo.spname
as
<procedure definition>
The good thing about such scripts is that running them multiple times doesn't create a problem- all the objects will already exist, so the script won't do anything a second time.
Setting up the server is pretty straight forward if you're using MS SQL Server. As for creating the database and tables, you generally only do this once. The whole point of a database is that the data is persistent, so if there's a chance that the database won't exist you've either got a) major stability problems, or b) no need for an actual database.
Designing the database, tables, and procedures is an entire component of the software development process. When I do this I usually keep all of my creation scripts in source control. After creation you will write the program in such a way that it assumes the database already exists - checking for connectivity is one thing, but the program should never think that there is no database at all.
you can make a script from all of objects that exist in your db. after that you can run this script from your code.
when you create your db script with script wizard in sql server, in "choose script options" section, set "Include If Not Exist" to yes. with this work done only if db not exists.

Make ADO.NET (and EntityFramework) release a database

I'm creating and dropping databases on the fly for some integration tests. I'm doing all the database management at the ADO.NET level. For the tests I'm using Entity Framework because the entities is one part of what I am testing. The problem is that after I do this:
using (ProjectEntities db = new ProjectEntities(cs)) {
}
I cannot drop the database anymore. It says it is in use. How do I release it so it can be dropped?
I actually had the same problem at the ADO.NET level and what I did was:
new SqlCommand("USE [master]", DatabaseConnection).ExecuteNonQuery();
but I'm not sure how to perform something with the same effect for the Entity Framework connection. I've trying manually disposing the db object (although the using clause should guarantee that) and I've also tried manually closing the db.Connection. Neither helped. If I could run SQL directly no the Entity Framework connection, I believe I'll be able to do it. Or maybe there's another way?
You might need to explicitly close all connections, I believe that the connection are being pooled and it's one of the pooled connections that is still maintaining an active connection to the DB. Try using SqlConnection.ClearAllPools
I blogged about a similar issue in Entity Framework Object Context - AWAITING COMMAND.

Categories