How to force a Database reset before seeding - c#

I am developing an utility that transfers the data from one structure into another data structure which is then stored in a SQl Server database controlled by Entity-Framework.
Each time I change the target database model I am doing the following;
Deleting the data from the target database.
Running "dbcc checkident("table", reseed)" on each table (many tables) to reset the ID values.
Reseeding the Database using "update-database"
After reading the following http://www.entityframeworktutorial.net/code-first/database-initialization-strategy-in-code-first.aspx I think I have two options. I don't think I want to roll my own initialiser.
The first option is to use one of the drop create strategies during development , (dropCreateifmodelChanges, or DropCreateAlways) Will the Drop Create process delete the existing target data, and reseed the Identity counter?
The second option is to somehow include the deletion, and the ID reset in the seed function. Can this be done? If so - how?
Is there a better option? Does anyone have any advice?

Me too had a same sort of situation and I have chosen the manual method which you have mentioned.B'cos it gave me more control over the automatic method.
But you can use the DropCreateDatabaseAlways strategy if you like.Yes,it creates fresh database.That means all the PK values will be reseeded.You can use this strategy only when you're developing the app on dev environment.

Related

How can I tell if a database record has changed?

I'm writing a process that will run on a schedule and periodically scan records in a SQL Server database and check for changes to those records. Unfortunately the records in this database are not versioned/timestamped in any way and I can't change the schema because it's not my database. Short of comparing every single field I don't have any idea how to check to see if a change has actually occurred.
Right now I'm using entity framework for all data access, but I can switch to direct queries if needed. Is there an easy way to do this?
EDIT: I need a way to check each individual record for changes, not a database/table as a whole.
I don't think checking each record can work for big databases (it can take forever)
But you could calculate hash for each row and store it in your apps database. Then on every run recalculate hash and compare with what's in your apps db.
Also I know you can't change schema, but maybe you could add triggers to monitored dataabse that will log changes?
Another option could be setting up replication and detecting changes (with triggers as above) in database that receive's replicated data (but I have to admit I never configured replication and I may be wrong about how it works).
If you're using SQL Server 2008 or greater, you may be able to make use of either Change Data Capture or Change Tracking. Here's a link to the MSDN documentation.

how to detect the new database when change database in asp.net mvc4

The problem that when i change the new database then application not detected the new database and retreive error
The model backing the 'DBContext' context has changed since the
database was created. Consider using Code First Migrations to update
the database (http://go.microsoft.com/fwlink/?LinkId=238269).
but i don't using Migrations so i don't update-database by Package Manager Console
How can i fix this problem?
Actually it does detect changes in your database. The database differs from the model. The error message.
This error is thrown when the hash stored in the migrations history table does not match a calculated hash. (Have a look at __MigrationHistory table, might be under system tables)
If you delete this table the check is essentially disabled. You can achieve something similar by adding Database.SetInitializer<YourContextType>(null) to the startup of your application. The latter disables database creation from within that application, so if you want to create the database by code, you would need to do this from a separate application (for example an console app). I prefer to go this way for web applications.
Secondly: if you change your database manually (change columns, add tables, etc.) you need to adjust your model. So for each DDL statement, change your code.
If you are not using code first, you could update your existing model in the designer.
I ran into this problem when I first started with code first and mvc. the answer below is absolutely correct but you should go to the ASP.net website and do some tutorials on code first migrations. you need a better understanding how update database and initialize and migrations work.

Best approach regarding to get least amount of lock time when reading/writing to access DB

I have a project where i am to syncronize a MS Access DB with a MySQL DB and i was wondering about best approach to read/write from/to the MS Access DB since it will lock the DB while i do it.
(There will be other applications reading/writing to the same Access DB so i would like to minimize the amount of time i lock it).
Does the language i choose make difference? I am most used to writing applications using C# and .NET.
Anyone more experienced out there with recommendations/experiences?
Store the queries your application will use exclusively for lookup purposes in the Access DB and as ReadOnly in the query properites. Then have your application query those ReadOnly queries, which will prevent unnecessary locks.
Keeping your update and insert SQL statements in the application short and simple will limit lock time to some extent as well.
I dont think the language matters much - you can use C# or VB in a .NET environment. Are you planning a real-time synchronization or an off-hours (lets say daily) synchronization of the two databases?
One approach for the synchronization would be to do a data dump of the tables to a text file, load them into properly indexed tables and then find updated records (using data access queries) and find new records (with an outer join) and append them to the datastore.
If your table do not contains primary key. Add one, let's name it "Id"
Create table "sync_log" to store changes.
one column for "SQL" to apply to target DB.
one column for this "SQL"'s execute status. (pending, finished)
one column for time of this "SQL", then you can apply the SQLs in original order to target DB.
Create Trigger for Create,Update,Delete
crate:
when create one row, your trigger will insert following line to another table "sync_log"
"INSERT into table T values(CA, CB, CC, CD)"
delete:
when create one row, your trigger will insert following line to another table "sync_log"
"delete from table T where Id = 99"
update: is similar, also identify target row by primary key "Id"
Let your app to poll the table "sync_log", apply new "pending" SQL to target DB, then update the SQL's status in "sync_log" to "finished".
This is one way sync, the another way sync is similar.
if (you are using Microsoft Access project)
then
{http://office.microsoft.com/en-au/access-help/create-a-trigger-adp-HP003085415.aspx }
else
{ Access macro events is similar to trigger. http://blogs.office.com/b/microsoft-access/archive/2009/08/13/access-2010-data-macros-similar-to-triggers.aspx
}

How to set up multiple Oracle databases (schemas) with the same user?

Our company inherited some software that runs on C# Visual Studio 2010, Windows 7 and Oracle 11g. After some effort we got the software working and got a stable database (schema) set up.
We are now starting the process of migrating some data from an old system to this "new" system. However, I don't want to mess up our working schema as I expect a bit of trial and error work will be needed with our data import.
I wanted to do the following:
Let's say our existing schema is called PROD. I wanted to create a second schema called TEST that we can use for the imported data. Then, in the C# code I can just switch the name of the datasource when switching between our two database schemas. The catch is that the username and password for this connection appears in a multitude of places scattered in the code. To avoid having to change user credentials in multiple places every time we switch between "db environments", I wanted to create a single user to have access to PROD and to TEST.
However, how to grant user privilege on specific schema? suggests this is not possible. Correct way to give users access to additional schemas in Oracle suggests a method for granting access on an object level, but this is insufficient: I basically want one single user to have access to two identical schemas (PROD and TEST). Once I've achieved this, I want to start modifying TEST to start with our data import.
I have also tried creating TEST as a separate Oracle Database installation on a different port, but when trying to create my user on this new instance I still get a conflict that the user already exists (since it was created for PROD in the original database installation).
My user already exists and has access to PROD. How do I give him access to TEST as well? Or how would one solve the more general problem of having a PROD and TEST database defined in an application that uses Oracle?
In MySQL this would be trivial, but I don't have any idea how to do this in Oracle. I am very new to Oracle.
The question of giving permissions has already been answered.
Now to your question, as a whole: Am I reading correctly that you want to update the database schema, but you want to keep it in the same database as another schema and run both in what appears to be a production database? If so, read that again to let it sink in how extremely dangerous that is.
When migrating from one "schema" to another, as a software update, it is safer to create a new database and migrate the data. This gives you plenty of shots, as you can blow away the new database as you tweak scripts.
If you want as little friction as possible in your software, you need to do a couple of things:
Refactor out the code from the moron who decided to hard code connection information in multiple places. You need to get the strings in one place and make sure you extract out the Data access layer (DAL) code into its own class.
Consider creating domain objects that do not rely on the database schema(s). I consider this mandatory, but you could get away without doing this. I would still create domain objects, even if they match the PROD schema tables, as you should not be using data constructs if you are moving from one schema to another.
Create an interface for your data access layer (DAL)
Map the current data schema, through the current DAL, to the domain objects, using the interface.
Map the new schema, through a new DAL, to the domain objects, using the interface.
Create a factory (or use the provider pattern) to determine which DAL object you are going to use (this makes the application configurable to old or new "schema"
I'm assuming that you have a schema PROD and a DBUSER which have some privileges to objects in this schema.
DBUSER's name and password is hardcoded all over the application.
You've created a new schema TEST which looks the same as PROD (including grants to DBUSER).
You want that wherever the application does something like:
UPDATE some_table set ...
It will update some_table table in TEST and not in PROD.
My suggestion is to use and change SYNONYMS, ie-
When you want to update some_table in PROD, do:
CREATE OR REPLACE PUBLIC SYNONYM some_table for prod.some_table;
and when you want to update some_table in TEST, do:
CREATE OR REPLACE PUBLIC SYNONYM some_table for test.some_table;
The connection to Oracle is not handled correctly in the C# code and this is what is causing difficulty.
If the Data Access Layer were defined separately as Gregory suggests or if a more generic naming convention were used in SQL statements as A.B's answer points to, then it would be much simpler to switch between two databases.
Since our mandate currently doesn't involve making any changes/refactoring of code, I am using a backup and recovery approach:
I create a backup of the working database. Then I do the necessary tests and changes on the database. If I need to revert back to the working database, I create a backup of the "testing" database again and restore the original working database, using the appropriate flag to replace existing tables in the case of a restore. This enables me to switch back and forth between the "working" database and the "test" database.
This is not ideal as it does take some time to execute the backups and restores, but works without affecting the C# code and gives the ability to do work on a "testing" database without affecting the working one. Since this is a temporary scenario until the "testing" database becomes working, this is the approach I'll be following.
As the other answers point out - there is a more generic need to fix/refactor/generalize the connection code - I believe that is the best approach and the only reason I'm not doing that immediately is because we are not yet mandated to change the code.

How to change database design in a deployed application?

Situation
I'm creating a C#/WPF 4 application using a SQL Compact Edition database as a backend with the Entity Framework and deploying with ClickOnce.
I'm fairly new to applications using databases, though I don't suspect I'll have much problem designing and building the original database. However, I'm worried that in the future I'll need to add or change some functionality which will require me to change the database design after the database is already deployed and the user has data in the database.
Questions
Is it even possible to push an updated database design out to users via a clickonce update in the same way it is for code changes?
If I did, how would the user's data be affected?
How is this sort of thing done in real situations? What are some best-practices?
I figure that in the worst case, I'd need to build some kind of "version" number into the database or program settings and create some routine to migrate the user's current version of the database to the new one.
I appreciate any insight into my problem. Thanks a lot.
There are some 'tricks' that are employed when designing databases to allow for design changes.
Firstly, many database designers create views to code against, rather than coding directly to the tables. This allows tables to be altered (split or merged, etc) while only requiring that the views are updated. You may want to investigate database refactoring techniques for this.
Secondly, you can indeed add versioning information to the database (commonly done as a 'version' table with a single field). Updating the database can be done through code or through scripts. One system I worked on would automatically check the database version and then progressively update the schema through versions in code until it matched the required version for the runtime. This was quite an undertaking.
I think your "worst" case is actually a pretty good route to go in this situation. Maintain a database version in the DB and have your application check and update the DB as necessary. If you build your updater correctly, it should be able to maintain the user's data. Depending on the update this might involve creating temporary tables to hold the existing data and repopulating new versions of the tables from them. You might be able to include a new SDF file with the new schema in place in the update process and simply transfer the data. It might be slightly easier that way -- you could use file naming to differentiate versions and trigger the update code that way.
Unfortunately version control and change management for databases is desperately, desperately far from what you can do with the rest of your code.
If you have an internal-only environment there are a number of tools which will help you (DBGhost, Red Gate has a newish app, some deployment management apps) but all of them are less than full solutions imho, but they are mostly good enough.
For client-shipped solutions you really don't have anything better than your worst case I'm afraid. Just try and design with flexibility in mind - see Dr.Herbie's answer.
This is not a solved problem basically.
"Smart Client Deployment with ClickOnce" by Brian Noyes has an excellent chapter on this issue. (Chapter 5)
ISBN 978-0-32-119769-6
He suggests something like this:
if(ApplicationDeployment.CurrentDeployment.IsFirstRun) {
MigrateData();
}
private void MigrateData() {
string previousDb = Path.Combine(ApplicationDeployment.CurrentDeployment.DataDirectory, #".\pre\mydb.sdf");
if(!File.Exists(previousDb))
return;
string oldConnString = #"Data Source=|DataDirectory|\.pre\mydb.sdf";
string newConnString = #"Data Source=|DataDirectory|\mydb.sdf";
//If you are using datasets perform any migration here, with the old and new table adapters.
//Otherwise use an .sql data migration script.
//Store the version of the database in the database, and check that in the beginning of your update script and GOTO the correct line in the SQL script.
}
A common solution is to include a version number somewhere in the database. If you have a table with miscellaneous system data, throw it in there, or create a table with one record just to hold the DB version number. Then whenever the program starts up, check if the database version is less than the expected version. If so, execute the required SQL CREATE, ALTER, etc, commands to bring it up to speed. Have a script or function for each version change. So if you see the database is currently at version 6 and the code expects version 8, execute the 6 to 7 update and the 7 to 8 update.
Another method we used on one project I worked was to ship a schema-only, no data database with the code. Every time you installed a new version the installer would also install the latest copy of this new blank database. Then when the program started it up it would compare the user's current database schema with the new database schema, and determine what database changes were needed on the fly. Like, if in the "reference schema" table Foo had a column named Bar, and there was no column Bar in the user's current database, we would generate a "alter table Foo add Bar ..." and execute it. While writing the first draft of the program to do this was a fair amount of work, once we'd done it there was pretty much zero maintenance to keep the DB schema up to date. The conversion was just done on the fly.
Note that this scheme doesn't handle DB changes that require changing data values, like if you add a new column that must be initially populated by doing some computation on data from other tables or some such. But if you can generate new data from old data, that must mean that the new data is redundant and your database is not normalized. I don't think the situation ever came up for us.
I had the same issue with an app in Android with an SQLite database adding a table. I changed the name of the database to include a version extension, like: theDataBaseV1, deleted the previous one and the app works fine.
I just changed the name of the database and the name in this line of code
private static final String DATABASE_NAME = "busesBogotaV2.db";
in the DBManager when its going to open.
Does anybody knows if this trivial solution has any unintended consequences?

Categories