How to copy an entire database with Entity Framework? - c#

The purpose of this task is to copy my database that contains the default values for all entities into a new created database. This task will be called when the program creates the database for the first time, so the newly created database would be filled with the values from my default value database.
The problem with just copy and paste database is that my default value database has messy primary keys. The value of each entity's primary key are not in order.
What I want is to create new database for the program, with the values copied from another database but with continuous primary key for each entity (1,2,3,4,5 no jumping).
The requirement is that the structure, references from the default value database has to remain the solid. For example when copied that entity A reset to id=1 from 5, then all the references changed to 1 as well.
How can I achieve this? Is there a fast way to do it instead of manually copying each entities? Because it is quite a large database.
Note: The default database context is identical to the newly created database context.

I my self done such a task few months back.There is no automatic way.You must do it manually.I would like to share the steps where I have used.
Step 1 :
I have created a new db (i.e. Migrated) by initialling (delete data and PK Reseed) the old db.After that I have an exact copy of the old db (i.e. schema only.No data)
Here is the script for one table
Use Migrated;
GO
delete from IpOccupantNotes
GO
--To Reseed the PK
DBCC CHECKIDENT ('[IpOccupantNotes]', RESEED, 0)
GO
Step 2 :
After that I have inserted the relevant data from the old db (Legacy in my case) as shown below.
INSERT INTO [Migrated].[dbo].[IpOccupantNotes] (Name, ZipCode)
select a.Name,a.ZipCode from [Legacy].[dbo].[IpOccupantNotes] as a;
GO
Note : If you have any question,feel free to ask.I'll help to you :)

Related

How to use Autocreated DataSet - TableAdapterManager

(Sorry for my bad English)
I have imported an access database to a C# winform project (.net 4.0) in visual studio 2013. It automatically creates a .cs file with a DataSet, TableAdapter and a TableAdapterManager.
I import data from the database to the DataSet, without error. I succeed to manipulate data, and save change to the database with TableAdapterManager.UpdateAll().
But now I try to insert new data, with relation between tables.
For example, a database like mine
Parent table :
autonum key
string parentname
Child table
autonum key
string childname
int parentKey
First try :
I create a new record with parentTable.AddparenttableRow(data ...) and get a parentRow.
I create a new record with childTable.AddchildtableRow(parentRow, data ...)
But if I call TableAdpaterManager.UpdateAll(), I get an error "can't add or modify a record because a related record is required in parentTable" (not the real message, it's a translation). I think that AddchildtableRow create the correct relation. And another problem appears : because of the error, the database isn't modified (which is good), but the records I had add, are always in the table of the DataSet.
So I try another method : TableAdpaterManager.tablenameTableAdpater.Insert()
First I insert a parentRow without any problem. But when I want to insert a childRow, the insert function asks for the parent key. But I don't have it (the insert parent call doesn't return the key).
My question is : how can I use the DataSet, TableAdapter and TableAdapterManager to insert records in the DataSet AND in the database, and with a transaction (if there is an error, the data won't be written to the database, and won't be added to the DataSet) ? And actually, how to correctly use these classes ?
Look up the typed dataset code. Switch between the default TableAdapterManager.UpdateOrderOption.InsertUpdateDelete to UpdateInsertDelete (msdn). For hierarchical updates you have to merge new values for your identity columns (msdn). Also see this post. The way ADO.NET deals with preventing collisions with it's disconnected dataset, it assigns negative IDENTITY column values, because it wouldn't know a possible positive number that IS NOT a collision as it's disconnected. Also managing a ##identity crisis with parent-child relations. The typed dataset technology also had issues with circular table references.

Alter column identity with Microsoft.SqlServer.Smo

I've trying to change a column IDENTITY using Microsoft.SqlServer.Smo from a table with no dependencies and with all the data loaded previously (from another DB) but i get an error like this "Modifying the Identity property of the Column object is not allowed. You must drop and recreate the object with the desired property". The thing is that i tried to do this with Management Studio and it has no problem with it. Do you have any suggestions?. Thanks in Advance
This is the code:
foreach (Column source in sourcetable.Columns)
{
try
{
if(source.Identity)
{
Column column = copiedtable.Columns[source.Name];
// column.Computed = source.Computed;
// column.ComputedText = source.ComputedText;
column.Identity = source.Identity;
column.IdentityIncrement = source.IdentityIncrement;
column.IdentitySeed = source.IdentitySeed;
column.Alter();
}
}
catch { }
}
Try doing it in SSMS again and choose to script the action out instead of applying it directly. You'll find that it creates a temporary table with the identity property set to true (and everything else the same), copies your data from the live table into the temp table, drops the live table, and renames the temp table to be the live table. You'll need to do something similar with SMO.
Copying the table is easy enough: iterate over the columns, indexes, foreign keys, etc and create your new table that way (taking care to set the identity property correctly properly before you call Create()). For moving the data, take a look at the Transfer class. Once that's done, it's a drop and rename (or a rename and rename if you want to be safe).
I'm a little surprised that SMO doesn't do this somehow under the covers (since SSMS uses SMO under the covers). If I find something else that makes it do this automatically, I'll let you know.
Are you trying to update an existing record, or add a new record? If you're adding a new record, then do an insert. If you're updating an existing record, don't overwrite the identity column value.
To insert identity values into a table in SQL Server you must tell the database to allow you to do this. Syntax is:
Set Identity_Insert [table] ON
When you're done you need to turn it off again.
Set Identity_Insert [table] OFF

Local Database in C#, Removing and Adding new column

I'm making a KTV System, and in part of that system I need to have a database where I can add Karaoke Songs, Store, Delete and Access them. I'm using c#, VS2012. Local database for my database, created a table with 5 columns (Code, Title, Artist, Genre, Path).
Set my code to be unique key and primary key, and also auto-incremented w/ default values(1,1)
Path Column is for the path of the video file to be played whenever a songs is chosen.
I didn't program the database functions, just drag and drop the built-in functions from the datasource like this:
Everything works fine, all the basic functions are working as it should be. When adding it produces negative and weird auto-incremented primary key(which is Code Column) but I know it's fine because everytime I re-run it is already correct. Now
And one thing, after I added my Data Connection and Data Source I also add a New data connection, connecting into the database that is located in the bin folder of the project. Because if I wont do that, everytime I refresh the database it will erase the data inside of it. Or everytime I close the project, it deletes the data, and it gets data from the Empty database from the Project folder not from the bin.
PROBLEM:
For example:
I tried to add 6 rows and then deleted them all, I was thinking that whenever I will add new rows the Code Column will start from 1 2 and 3 again but not, 7, 8 and 9. It seems like it is skipping because there are already 6 existing columns but checked the data table in the database, it isn't. The deleted 6 columns are also gone, same as with the data in the form.
-
and something like this also
I want the Code Column to be always sorted, if ever I delete or Add new rows into the local database.
It all depends how you delete your data.
DELETE * FROM ...
will not affect your auto-increment primary key generator. However,
TRUNCATE TABLE ...
will reset the counter to its initial seed.
May I suggest that you don't attempt to control your auto-generated ID (code), but introduce a new column in your query using the ROW_NUMBER() function.
If you want to reset your primary key or code column truncate the table
Truncate Table tableName
Truncate like others have said will work or with DCBB CHECKIDENT:
DBCC CHECKIDENT (TABLENAMEHERE, RESEED, 0)

How Can I Programmatically Override the Auto_Increment Value When Inserting Into a DB

I have just started converting an old web application into a new structure.
I have a newly designed supplier table created in a MS SQL Server 2012 DB, which I am in the process of transferring the supplier data from the old DB to.
I have a C# MVC application set-up using the new DB as the data context. At present the application gets the data from the old applications DB, checks it, reformats it where necessary and inserts it into the new database in the desired format.
However as users of the application have got used to the supplier IDs in the old DB, I don't want to change the IDs, however as the id field in the new supplier table is an auto increment, it doesn't copy the ids from the old database. It just simply increments.
Does anybody know of anyway the auto increment can be overridden programmatically in the c# code for the initial import stage of the project. Once the data from the old system has been imported, I would then like to revert back to auto increment.
You can set identity insert on. However, if the users know the keys I've found they start asking to change them. I might consider the old keys as the user identifier and create a new surrogate key they won't ever see.
You can turn off the identity generation on the server temporarily during the bunch of inserts, then turn it on again. Try submitting this query to the server:
SET IDENTITY_INSERT dbo.sometable ON ;
INSERT INTO dbo.sometable (id,.......) VALUES (456,.......) ;
INSERT INTO dbo.sometable (id,.......) VALUES (276,.......) ;
INSERT INTO dbo.sometable (id,.......) VALUES (387,.......) ;
SET IDENTITY_INSERT dbo.sometable OFF ;
It just disables identity creation, then does the inserts (note that the column and value lists do include the id), then restores the default behavior.
In Sql Server, you can set the ID field to non identity. This will make it not auto increment

What happens when saving objects using Entity Framework?

Probably sounds like a silly question, but there is an aspect about it I would like to know:
I'm working with objects that have a Guid-property for PrimaryKeys, which gets auto-generated in the database. I am using Entity Framework, Code First. If I do a Console.WriteLine with this property before saving, the value is
00000000-0000-0000-0000-000000000000.
After using Add and SaveChanges in the context, if I do a Console.WriteLine again with the same property, I have a value:
615f98eb-4ced-422a-877f-b9caa6f2b91f
Obviously, the object in memory has been updates. But I want to know how. The Guid is genereated in the database, so what happens?
Does the Guid-property of the object simply get updated from the database through EF, or does EF reload the entire object into memory after saving it in the database?
I would like to know, because that will determine how I design NUnit-tests in the same project.
Your EF object is updated when you call domainContext.SaveChanges(); Your new Id is generated by SQL database and value of Id is return value from DB. It is same for data types int, Guid and similar.
EF does not only submit an Insert/Update statement, at the same time it does a get statement to retrieve the generated primary key. In fact it is one single query. Your entity's primary key is then updated with the retrieved one. No magic behind this.
That's also one of the reason why batch updates / inserts are not supported. Every entity has to be updated / inserted on its own.
This is a query that is being executed when inserting an entity with a computed int primary key:
insert [dbo].[TestTable]
([Name])
values ('myname' /* #0 */)
select [ID]
from [dbo].[TestTable]
where ##ROWCOUNT > 0
and [ID] = scope_identity()
As you can see, the insert statement is followed by a select statement retrieving the computed columns (in this case ID). If there are more computed columns they're all selected here.

Categories

Resources