I've been working on a CMS based in ASP.NET MVC2 using a poco based linq-to-sql repository that is connected to a SQL 2008 database.
I'm nearing completion on the CMS and now I'm thinking about deployment. Ideally, I would like the install process to be something like this:
Copy CMS solution to server location
Create empty database
Change db connection string in web.config to new database
Run script to create db tables (including relationships, constraints, and default data).
I'm not sure where to start with this kind of project. I have limited experience working with Stored Procedures. If it's possible to do this progmatically in C# that would be preferable because it would be easier for me to work with.
Any thoughts on where I should start with this?
Edit - New thoughts
I wonder how difficult it would be to just have a database file (mdf?) that could just be renamed and copied to the sql server. Is that even possible?
I would suggest scripting out the creation of your new database and including it as a step in your application install.
You can let SQL Enterprise manager do a lot of the work for you to generate the script too. If you are using enterprise manager just right click your database and select:
Tasks -> Generate Scripts
In that wizard select your database and the "Script all objects in selected database". That will end up generating a create script for your entire dB.
You can then take that script file and include it as a resource in your setup program, and run it during setup to create out your full dB.
A good thing to think about if you are going this route is Type data. You may want to include another script step that will populate your type data as the 1st script will only generate your dB, tables, and procs.
The two ways I can think of doing this off the top of my head are:
1) Web Setup projects - Similar to this post here and add your own custom actions
2) Make it so the first time your application runs it searches for a DB and if one is not found it gives you the option to add the DB/Connection String.
Both of these can be done in C#. You won't be using Stored Procedures until you have a DB setup because that is where the SPROCS reside.
Embedding the database is probably your best bet. You can use an .mdb, or SQLite or similiar. If your using .mdb, just create a template .mdb, then make it a resource of the project. Then you can copy it to the destination and modify it from there.
I would use SQLite, as its open source, and then you don't have to mess with changing the connection string because you'll just be using the program's install directory to store it.
Related
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
I have a database project in my solution and the requirement is simple (not so sure about the implementation).
Is there a way to deploy the database project programatically?
PS: I don't mean attach an MDF file. I mean deploy the database to a SQL Server instance.
You can add the script for create the database as an "Embedded Resource" then execute it when needed with the standard ExecuteNonQuery(...). But you probably need to upgrade it in the future so the idea is, a part the first drop, have some table somewhere keeping the schema version, then have multiple embedded resource contatining script to jump to one version to the next one. When the service start check the version against the expected one, if not the same launch the needed script(s) to reach the current version.
You can use plain sql commands to achieve this.
http://msdn.microsoft.com/en-us/library/49b92ztk(v=vs.80).aspx
http://www.codeproject.com/Articles/16231/Deploy-your-Application-and-Database
Best regards
Create the database SQL however you like and include it in your project. Then simply execute the SQL script against the server.
I use this when I include SQLite databases in my project.
Currently, changes to the database are made through the SQL Server Management program. IF a table changes, sqlmetal is run to regenerate the linqtosql classes and development continues. However, this makes deployment a pain, as you have to go through and manually update the deployment database (and any other databases used in the development cycle). It would be nice if we could use C# to generate these changes, as it would help eliminate human error and have the added benefit of being able to keep the database structure in git. Right now, the only representation of the database is in the generated linqtosql classes.
I've been looking around for a nice library that can handle this sort of thing, but the main solutions seem to be: keep a sql generation script, or embed sql in C# classes that can be run to make changes to the database. Both of these seem to be very non-ideal situations, as you lose the nice strong-typing that C# provides. It seems like there should be a way to do this using pure C#.
I've seen hints of being able to do things like generate databases from POCOs using both the entity framework and linqtosql, but I'm having a hardtime finding specific examples of that being used. Additionally, I haven't been able to discover if those have a graceful (i.e. data preserving) way of handling changes to the database after the initial table generation.
Are there any projects out there that solve this problem?
There exist several tools that help you with schema (and data) migrations of your database: RikMigrations, Migrator.Net and Machine.Migrations. Hope that helps.
Wizardby looks also promising: It provides database independent DDL scripts and automated migrations between different versions of a schema.
VS2010 can operate version control on your database schema through a Database Project. There are other tools out there for DB development that offer version control, you'll need to search to find them and compare pricing.
I prefer to version using sql scripts. Works pretty well, is free, supports updates, easy to version, works well with traditional source control methods.
First,
Create your DB
Use the Database Publishing Wizard to publish the database as a .sql script
Add a version number to the script
Add to your solution
Check into source control.
As updates are made,
Script updates to the previous schema as .sql files
Add a version number to the script that is incremented from the previous version
Add to your solution
Check into source control.
It sounds like you need a tool like Migrator.NET to manage your database migrations. We use it with a call from our site start-up to migrate the database as needed for any particular version.
I have toyed with an idea for creating a cleaner interface and someday hope to get around to implementing it, but other priorities have pushed that back. For now we are using raw sql strings in our migrations because there isn't a sybase driver implementation (outside of a very ugly hack I have written to manage the versioning table).
Redgate software offers something that may be really useful for you. It's called SQL Packager and it does it's job pretty well.
Features:
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
They also offer SQL Source Control which also may be useful to keep things nice and easy.
As an addon to MadBoy, SQL Packager can also launch the package as a C# project.
Red-Gate's SQL Compare is excellent as well, and as some of the banners on SO indicates, there is new SQL Source Control available as well.
Then they have their SQL Comparison SDK.
The trick here is to rely on the database being the single source of truth for your Linq schema, not the generated classes.
We use Linq to SQL extensively in our dev shop, and work as follows:
1. Create your database (working copy) from version control (baseline).
2. Modify your database any which way you like.
3. Generate Linq to SQL classes from the (working) database.
4. Create patches to update your baseline database to your working copy.
5. Check in and share these patches with all developers.
For a very quick and easy way of generating baseline and working copy databases, try DBSourceTools. http://dbsourcetools.codeplex.com
Have fun.
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.
For some integration tests I want to use LINQ to SQL to drop/re-create the test database. I've had this working fine before, however in this project the database is split up into several schemas.
When I try to run the ctx.CreateDatabase() command I'm getting this exception:
The specified schema name "xyz" either
does not exist or you do not have
permission to use it.
The login I'm using to do this has the role dbcreator - Does it need further permissions? Surely a login with persmissions to create a database should be able to create everything contained in that database also?
Update:
Since it looks like there isn't a solution to this problem using LINQtoSQL, does anyone have recommendations of any similiar tools to generate a db that are preferably free? Ideally I don't want to have to muck about hand writing sql build scripts.
From what I've read, the CreateDatabase() method is limited in what it can reproduce of the original database. It won't recreate things like triggers and check constraints, and I'm guessing it doesn't create custom schemas either. You may want to look into creating the database using a SQL Server .mdf file instead to work around this issue. See this blog entry for more details on some of the limitations of CreateDatabase().
I generally do this sort of work in NAnt to create, initialize the database, create users, add logins, etc....and also roll back capabilities. I have written on this topic quite a bit if you are interested:
Build automation with NAnt
Continuous integration with CruiseControl.NET
I will have to see if I can get LINQ to SQL to work in the way you are trying to use it...that sounds like what we used to do with NHibernate.
The dbcreator fixed server role grants you the permission to create a database. If you create a database, you are the dbo of said database and as dbo you have absolute power in the database, includding the power to create, alter and drop any schema and any object contained in any schema.
the problem with LINQ's CreateDatabase() is not permission, is code quality. The generated SQL code simply does not create the needed schema, so the Create table statements fail because the schema does not exist.
Your best choice, if you can afford it, is to add a VSTS Database Edition GDR R2 project to your solution and declare all your database objects in the Database Edition project (part of your solution). You'll be also getting the added benefit of storing all your database objects in a proper source control solution. The output of the Database project would be a .dbschema file containing the definition of your database. At deployment time (test or real) you would run the VSDBCMD Deployment and Schema Import tool to import your .dbschema into the target server. The tool is capable of doing initial deployment of your schema, as well as further upgrades (deploy only differences). The VSDB solution would allow you to controll all your database objects: tables, indexes, views, schemas, field contraints, table constraints, triggers, procedures, users, permissions, logins etc etc. It really covers all the objects that can be defined in SQL Server.
Actually LINQ to SQL does support schemas, but not every Sql Server edition does. To enable CreateDatabase() to generate them the DataContext must be aware that the target database does support them. It can be done by setting the provider on the DataContext:
[Provider(typeof(Sql2008Provider))]
public class CustomDataContext : DataContext {
...
}
Your user also requires db_dlladmin for that database.
I would definately look at Entity Framework, which I am beginning to look into these days. It's an OR/M, and will most definately suit your needs, and alot more once the next version is released.
Entity Framework is also a brain-child of Microsoft and can be found here: http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx
One thing to remember between LINQ to SQL and LINQ to Entities is that you are programming against a model, and not the database.