Adding data to SQL tables in C# - c#

This may or may not be a noob question, so I'm sure it should be solved easily enough.
I'm trying to use a table in a .mdf database for a contacts list programme I'm writing. For the ID for each of the entries I put, I've got an Identity seed of 1000, with in increment of 1. This works fine when I input things directly into the table. The first entry is 1000, the second is 1001 and so on. I put some text boxes onto the form, and dragged each data source from the table onto their respective text box, so that new entries can be added from the form. The first two entries, which I added directly into the table, show up fine on the form, with their ID as I've previously stated. It's when I try to add a new entry using the form and the controls that I've created that problems arise.
When I add a new entry, the Contact ID for the new entry is set to -1, then -2 and so on. Why is this happening, and how can I fix it?
Relevant snips:
First entry is in there and works fine
New entry has an ID of -1 for some reason

It is default value for IDENTITY fields.
As far as you cannot know which will be the value of an IDENTITY fields unless you insert the record, by default it show -1
The best way to avoid it, it now showing this field when you dateset is on INSERT mode.
In fact, if you try to set it value manually, you will get an error.

Make ID field read-only or don't show it altogether. The INSERT sql for your form should not include identity, i.e.
Insert into contacts (name, company, telephone, mobile, email)
Output INSERTED.*
Values (. . . . .)
If you in c# do command.ExecuteReader using above sql, you will get back all values including ID

Related

Why does sql update creates a new row in my database (C#)?

I'm working on my own asp.net mvc project and i have a little problem with updating my mysql database.
I have a table in my database with the following columns: (account, firstname, lastname, birthday, phonenumber, profilepicture) all of them are varchar columns and the table is called 'usersprofile'.
Here you can see one row in the table.
https://imgur.com/a/86z68Om
Everytime i try to update any column i get a duplicate primary key error for the primary key column 'cause the update command tries to create a new line.
Here you can see my C# code for the update:
https://imgur.com/a/h2uNzSD
It was a little bit more complex but it didn't work so i decided to make it more simpler by changing it so i can test if it works or not. If i'm correct i used the syntax well and i really have no idea why the update method wants to create a new row in my database.
Do u have any idea?
One of my colleague had the same issue, The Id wasn't auto-generated. You could add that to the Id property in your class. (DatabaseGenerated(DatabaseGeneratedOption.Identity)]).
To manually tackle this(Crude) => Specify the previous Id number to be sure it's updated.
But it's certain you're trying to insert into the table.

How to detect which column's value has updated in a Table

Suppose I have a student registration form with 85 fields in my c# project and there are three buttons Save, Update, Delete.
The person who update the field knows very well that which field has updated but how other person will know that which field has updated ? Because...
If I click update button without changing any value, the Update query execute and the same update query execute too when I click update button with some changes.
So I want that database should detect which field has updated in update query.
The traditional way says that store the previous values and then compare them with new values one by one field. But this slow down the performance.
Any smart way ?
You can implement optimistic concurrent using a rowversion column. This avoids the need to check the old/new values of each column individually. Specify the original rowversion in the WHERE clause of the UPDATE statement and verify a row was updated. Proc example:
CREATE TABLE dbo.OptimisticConcurrencyExample(
OptimisticConcurrencyExampleID int NOT NULL
CONSTRAINT PK_OptimisticConcurrencyExample PRIMARY KEY
, Column1 int NOT NULL
, Column2 int NOT NULL
, Column3 int NOT NULL
, RowVersion rowversion
);
GO
CREATE PROC dbo.UpdateOptimisticConcurrencyExample
#OptimisticConcurrencyExampleID int
, #Column1 int
, #Column2 int
, #Column3 int
, #OriginalRowVersion rowversion
AS
UPDATE dbo.OptimisticConcurrencyExample
SET
Column1 = #Column1
, Column2 = #Column2
, Column3 = #Column3
WHERE
OptimisticConcurrencyExampleID = #OptimisticConcurrencyExampleID
AND RowVersion = #OriginalRowVersion;
IF ##ROWCOUNT = 0
BEGIN
RAISERROR('data updated or deleted by another user', 16, 1);
END
GO
When an optimistic concurrency error occurs, the app code can refresh the data with the current values, let the user know someone else updated the row, and allow the user to re-enter changes. You could get fancy and transparently merge pending changes in code (checking old/new values for each column) and notifying the user only if a conflict occurs. Similarly, you could present the user with a merge form after a conflict with the entered and current values side-by-side and the different values marked, etc.
But given conflicts are typically rare (unlikely that different users will update the same student record at the same time), the additional development effort may not be worth the trouble.
I have one way to do that thing using table versioning using that you can maintain every update, create, delete the record.
Tutorial for table versioning
Another Tutorial
The second way is you have to add audit table or field that store SQL query and also store which user change the data and also store last modified date like that.
Why do you need a save button and an update button? Same thing, right?
Modify the logic in your program to allow an update only if the user
changes the data on the student registration form relative to the
data in the database.
Read record from database
Store record data in a local DataRow or List
Load data onto the student registration form
update_button.enable = false
delete_button.enable = true
Create TextChange event methods for each TextBox on the student registration form
When a TextChange event method fires, compare the TextBox text to the corresponding DataRow field or List item (case
insensitive).
If they don't match, enable the update button
If the user clicks the update button, update the record and disable the update button

Update master/child rows

I have tables Cases and Degrees with relation Cases.CID - CDegrees.CID. CID is Primary Key of Cases with AutoIncrement.
Both tables are used in one form and it's assumed that user can add new records to both tables same time and than save whole master/child data in one GUI action.
So in Dataset where I created FK I set "Both Relation and Foreign Key Constraint" to ensure during update of new record in Cases table, retrieved IDENTITY value will cause child records to update from -1 to retrieved CID value.
When I update Cases adapter, it causes to retrieve an new IDENTITY value and cascade update in CDegrees child record works ok too. But CDegrees's update causes Insert script with [CID]=-1 (original value). I changed Insert parameter #CID of CDegrees to "Proposed" version but same happens (seen in SQL Profiler).
Actually my task is mach more complicated, I just simplified task to localize my problem.
To describe more clearly.
before update
Both [Cases] and [CDegrees] have one new records with [CID]=-1
after [Cases] update both [Cases] and [CDegrees] have new CID identity value, just [CDegrees].[CID] "Current" value is -1 and "Proposed" is retrieved identity.
But when I call [CDegrees]'s dataset update, it sends Insert Command to SQL with [CID]=-1 regardless that I specified #CID parameter source as proposed value of [CID].
That is strange and funny. It appeared that calendar control on detailsform somehow causes but preventing details data cascade update according master identity value of CID field.
I just changed date field bound control from MonthCalendar to DateTimePicker and it worked.

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

Categories

Resources