Value Insert error in LINQ/C# for Column identity - c#

The Below code i used.
SQL table name: tbl_Student
Columns : student_id (identity), Firstname, Lastname, Location, Email.
When i submit the below code. The following error will occur. I am new to this concept. I don't know how to manage the identity column. pls help.
Can't perform Create, Update or Delete operations on
'Table(tbl_Student)' because it has no primary key in c#
tbl_Student ts = new tbl_Student();
ts.Firstname = textBox1.Text;
ts.Lastname = textBox2.Text;
ts.Location = textBox3.Text;
ts.Email = textBox4.Text;
db.tbl_Students.InsertOnSubmit(ts);
db.SubmitChanges();

As specified :
Can't perform Create, Update or Delete operations on a table because it has no primary key in c#
You will either need to try executing the command yourself ( via ExecuteCommand), or better yet - modify your tables to have a key, which is highly recommended.
Note: As I specified in the comments below, after adding the key, regeneration of the models is needed.
Example for executing a query yourself:
db.ExecuteQuery<Studnet>("INSERT INTO tbl_Student VALUES(Firstname ,LastName, Location, Email)");

Did you have a primary key in the database table when you generated the Linq to SQL classes through the designer? Just to make sure, regenerate these classes through the designer.

Related

Adding SQL Server ID Increment upon registration

How would I retrieve an Id from my SQL Server table, add +1 to it, and register that number to the next Id when someone registers into my program?
This is my code so far. The ?? means I don't know what would go there for this to work.
SqlCommand hi = new SqlCommand("SELECT MAX(Id) FROM Table");
hi.CommandType = CommandType.Text;
hi.Connection = connection;
hi.Parameters.AddWithValue("#Id", ??);
For example, last Id was 14. Now someone is registering and I want it to say 15 in the SQL Server table under Id.
I'm not sure what your full table structure is like, but the functionality you're describing is available natively in a SQL Server databases, and it's called an identity column. The way you would implement it is like this:
CREATE TABLE MyTable
(
Id int not null identity(1,1),
Name nvarchar(255) not null
# other columns go here...
)
You should be able to alter an existing table to make an Id column use identity, the only catch is you can only have one identity column per table.
When you want to insert a new record into the table, you can leave the identity column out of your insert statement, as SQL Server will fill it with the appropriate value:
INSERT INTO MyTable (Name)
VALUES ('My Name')
I would suggest to handle it at database level by making ID column auto increment.
If you want to do it from your code then you have to make additional hit to database to get last ID before you make your insert call to add data.

Insert 2 rows in tables with foreign key relation without knowing the primary key of the main table

I have the following databasescheme in SQL Server Manager 2014.
I'm making a C#-windows application in Visual Studio and I want to insert a new orderline and a new order. The problem is that the primary keys of both tables, auto-generate in server manager, so I haven't yet the value of the primary key of the order-table, but I need that value to fill into the foreign key of the orderLine column. How can I insert these two rows.
Kind regards
SCOPE_IDENTITY returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.
You can use SqlCommand.ExecuteScalar to execute the insert command and retrieve the new ID in one query.
using (var con = new SqlConnection(ConnectionString)) {
int newOrderID;
var cmd = "INSERT INTO Order (column_name) VALUES (#Value) ;SELECT CAST(scope_identity() AS int)";
using (var insertCommand = new SqlCommand(cmd, con)) {
insertCommand.Parameters.AddWithValue("#Value", "bar");
con.Open();
newOrderID = (int)insertCommand.ExecuteScalar();
}
}
This will allow you to catch the last generated OrderId and use it in the Insert Statement for the OrderLine table.
Another option is to use the following SQL code:
string command = "INSERT INTO Order(totalPrice) OUTPUT INSERTED.ID VALUES(#totalPrice)" // this will be a parameter from your code
Then the OrderId can be taken from :
Int32 orderId = (Int32) command.ExecuteScalar();
While scope_id() works fine for single rows, you really should learn to use the output clause as scope_id() is useless for multiple rows inserted with a single sql statement.
See this prior question for a simple example of using the output clause.
Obviously this allows you to retrieve more than just the identity value too.
ADDED
Also useful is the new sequence feature (added for 2012) instead of using identity. If your are coming from other databases this may seem a more natural solution.
Sequence is very useful if you would like to share a single sequence among several tables -- although this is an uncommon design I have used it a few times.
If you're using any form of direct SQL, you need to receive the SCOPE_IDENTITY() value immediately after inserting your order, then use that value to insert your lines.
INSERT INTO Order
SELECT SCOPE_IDENTITY() AS NewId; OR RETURN SCOPE_IDENTITY(); OR DECLARE #OrderId INT = SCOPE_IDENTITY();
INSERT INTO OrderLine
Otherwise, use Entity Framework and it will automatically retrieve your new IDs and assign to dependencies.

Violation of PRIMARY KEY constraint error occurred in the insert sql right after the update sql returns 0 rows

I have the code like this
if (***Adapter.UpdateRow(memberID, Type) == 0)
{
***Adapter.InsertRow(memberID, Type);
}
but i get the Violation of PRIMARY KEY constraint error in the InsertRow.
the primary key in table is memberID and Type and here are the sqls:
InsertRow
string sql = #"
INSERT INTO TBL***** (
MemberID
, Type
, DateTime
)
VALUES (
#MemberID
, #Type
, GETDATE()
)
";
var cm = new SqlCommand(sql.ToString());
cm.Parameters.Add("#MemberID", SqlDbType.Int).Value = memberID;
cm.Parameters.Add("#Type", SqlDbType.Int).Value = (int)Type;
return this.ExecuteNonQuery(cm);
UpdateRow
string sql = #"
UPDATE TBL****
SET DateTime = GETDATE()
WHERE MemberID = #MemberID
AND Type = #Type
";
var cm = new SqlCommand(sql.ToString());
cm.Parameters.Add("#MemberID", SqlDbType.Int).Value = memberID;
cm.Parameters.Add("#Type", SqlDbType.Int).Value = (int)Type;
return this.ExecuteNonQuery(cm);
i'm really want to now the reason why it happened (right after the update one).
thank you all for your comments .
I think that maybe there are two threads that conflicted with each other ,then the first one inserted successfully but the second one failed.
I have this logic in my web site's user registration and it happends when the user click the activation link in the register mail.
I think the user may double click(with a high speed) the link and the error occured.
A Violation of PRIMARY KEY constraint means that you're attempting to insert a record that will create a duplicate on the primary key fields.
Check the table definition and note the fields in the primary key.
If you can post the table definition in your question for other readers even better :)
Edit after comment added
Given your primary key contains both MemberId and Type, there is likely a logic error in the update, or there is a scenario where no results are returned in the update.
You should use an upsert (update or insert) as Allan S. Hansen has suggested.
The logic is as follows:
Check if the record exists
Either update if exists or insert a new record
You wouldn't normally perform an update to check if the record exists, as the update may perform no changes in some scenarios.
Your code is relying on the ROWCOUNT being returned after executing DML. This is not guaranteed to happen, because is subject to SET NOCOUNT setting. When SET NOCOUNT is ON
the returned rowcount is always 0, irrelevant how many rows where actually updated. The returned rowcount is what ExecuteNonQuery() returns.
You could check and ensure SET NOCOUNT is OFF but it would still be a lost cause. The code you propose is fundamentally flawed in presence of concurrency: multiple client apps can run the UPDATE simultaneously and all conclude they should INSERT and then only one would succeed. The correct way to do this is to use MERGE statement:
MERGE INTO TBL**** as t
USING (VALUES (GETDATE(), #MemberId, #Type)) AS s (date, MemberID, Type)
ON t.MemberID =s.MemberID and t.Type = s.Type
WHEN MATCHED THEN
UPDATE SET t.DateTime = s.date
WHEN NOT MATCHED BY TARGET
INSERT (MemberID, Type, DateTime) VALUES (s.MemberID, s.Type, s.DateTime);
This is a single statement that does wither the INSERT or the UPDATE without the concurrency risks.

How to insert to table with one-to-one relationship via dataset

I use asp.net 4 and DataSets for accessing the database. There are two tables with one-to-one relationship in the database. It means that both tables have the same column as a primary key (say Id), and one of tables has #identity on this column set.
So in general if we want to insert, we insert first into the first table, than insert into the second table with id.table2 = id of the corresponding record in table1.
I can imagine how to achieve this using stored procedure (we would insert into the first table and have id as an out parameter and then insert into the second table using this id, btw all inside one transaction).
But is there a way to do it without using a stored procedure? May be DataSets \ DataAdapters have such functionality built in?
Would appreciate any help.
Today it is so quiet here... Ok if anybody is also looking for such a solution, I've found a way to do it.
So our main problem is to get the id of the newly created record in the first table. If we're able to do that, after that we simply supply it to the next method which creates a corresponding record in the second table.
I used a DataSet Designer in order to enjoy the code autogeneration feature of the VS. Let's call the first table TripSets. In DataSet Designer right click on the TripSetsTableAdapter, then Properties. Expand InsertCommand properties group. Here we need to do two things.
First we add a new parameter into the collection of parameters using the Parameters Collection Editor. Set ParameterName = #TripId, DbType = Int32 (or whatever you need), Direction = Output.
Second we modify the CommandText (using Query Builder for convenience). Add to the end of the command another one after a semicolon like that:
(...);
SELECT #TripId = SCOPE_IDENTITY()
So you will get something like this statement:
INSERT INTO TripSets
(Date, UserId)
VALUES
(#Date,#UserId);
SELECT #TripId = SCOPE_IDENTITY()
Perhaps you will get a parser error warning, but you can just ignore it. Having this configured now we are able to use in our Business logic code as follows:
int tripId;
int result = tripSetsTableAdapter.Insert(tripDate, userId, out tripId);
// Here comes the insert method into the second table
tripSetTripSearchTableAdapter.Insert(tripId, amountPersons);
Probably you will want to synchronize this operations somehow (e.g. using TransactionScope) but it is completely up to you.

Why does a user have to enter "Profile" data to enter data into other tables?

EDIT
It appears the user has to enter some data for his profile, otherwise I get this error below. I guess if there is no profile data, the user can not continue to enter data in other tables by default? I do not want to make entering user profile data a requirement to use the rest of the sites functionality, how can I get around this?
EDIT 2
OK I will try: To DROP a FOREIGN KEY Constraint However, my table doesn't have a foreign key column....?
(Notes- Ref1, Ref2)
Original Question:
Currently I have been testing everything with the same user and everything has been working fine.
However, when I created a new user for the very first time and tried to enter data into my custom table, I get the following error.
The INSERT statement conflicted with
the FOREIGN KEY constraint
"FK_UserData_aspnet_Profile". The
conflict occurred in database
"C:\ISTATE\APP_DATA\ASPNETDB.MDF",
table "dbo.aspnet_Profile", column
'UserId'. The statement has been
terminated.
Not sure why I am getting this error. I have the user controls set up in ASP.NET 3.5 however all I am using is my own table or at least that I am aware of.
I have a custom UserData table that includes the columns:
id, UserProfileID, CL, LL, SL, DateTime
(id is the auto incremented int) The intent is that all users will add their data in this table and as I mentioned above it has been working fine for my original first user I created. However, when i created a new user I am getting this problem.
Here is the code that updates the database.
protected void Button1_Click(object sender, EventArgs e)
{
//connect to database
MySqlConnection database = new MySqlConnection();
database.CreateConn();
//create command object
Command = new SqlCommand(queryString, database.Connection);
//add parameters. used to prevent sql injection
Command.Parameters.Add("#UID", SqlDbType.UniqueIdentifier);
Command.Parameters["#UID"].Value = Membership.GetUser().ProviderUserKey;
Command.Parameters.Add("#CL", SqlDbType.Int);
Command.Parameters["#CL"].Value = InCL.Text;
Command.Parameters.Add("#LL", SqlDbType.Int);
Command.Parameters["#LL"].Value = InLL.Text;
Command.Parameters.Add("#SL", SqlDbType.Int);
Command.Parameters["#SL"].Value = InSL.Text;
Command.ExecuteNonQuery();
}
Source Error:
Line 84:
Command.ExecuteNonQuery();
Sounds like you have a foreign key constraint between the UserData and Profile tables. When there is not a record in asp_Profile that has a UserID value that equals UserProfileID in your new record in UserData table, you get this error. Not sure what your goal is, but sounds like you should just delete the FK_UserData_aspnet_Profile constraint, and then make UserData.UserProfileID nullable, since there will not always be a record in profile corresponding with your UserData table.
Make UserProfileID nullable and pass DBNull to UID parameter if the user didn't enter the data.
This means that the value you're trying to enter into the UserProfileID column does not exist in any row of the Profile table in the UserID column.
Maybe ProviderUserKey isn't what you should use here.
This took care of it -
ALTER TABLE UserData
DROP CONSTRAINT FK_UserData_aspnet_Profile;

Categories

Resources