npgsql returns table schema without primary key - c#

I'm trying to find a universal way of getting the column with the primary key inside a given table. I've tested the following code out
SqlCommand cmd = new SqlCommand(sql, conn);
var reader = cmd.ExecuteReader(CommandBehavior.KeyInfo);
var schemaTable = reader.GetSchemaTable();
This code works perfectly fine and all is good, I can find the column with the primary key easily from it for any SQL Server database, but when I try to use the Npgsql library on a PostgreSQL database, it labels all the columns (whether a column is the primary key or not) inside a given table as false.
Has anybody faced this issue before?
PS: I know that there are ways to get what I want using a query hack (INFORMATION_SCHEMA I mean), but I don't want to walk that road.
Updated
Postgres Version: 14.5, NpgSQL: 6.0.6
Example code
CREATE TABLE accounts (
user_id serial PRIMARY KEY,
username VARCHAR ( 50 ) UNIQUE NOT NULL
);
Whether I'm using a primary, or an identity it's still giving me false, on the other hand, in the below table the isKey column is marked true, but I'm in need of the isIdentity column to be marked true, any potential fixes?

Related

Postgres column timestamp is of type timestamp but expression is of type text

I just started working with PostgreSQL for a timeseries database using timescale. Before i use timescale i wanted to setup a little test for inserting data.
Whilest inserting data from c# into a postgres database table i run into the following error:
column "timestamp" is of type timestamp without time zone but expression is of type text
I was looking trough the documentation of postgres but couldnt find the solution.
this is my table:
CREATE TABLE measurement_ms (
id SERIAL PRIMARY KEY,
value VARCHAR(255) NULL,
timestamp TIMESTAMP(6) NULL,
machine_id INT NOT NULL,
measurement_type_id INT NOT NULL,
point_of_measurement_id INT NOT NULL,
FOREIGN KEY (machine_id) REFERENCES machine (id),
FOREIGN KEY (measurement_type_id) REFERENCES measurement_type (id),
FOREIGN KEY (point_of_measurement_id) REFERENCES point_of_measurement (id)
);
and this is the code in c# i'm using to insert the data into the table:
NpgsqlCommand addMeasurementQuery = new NpgsqlCommand("INSERT INTO measurement_ms (value, timestamp, machine_id, measurement_type_id, point_of_measurement_id) values(#value, #timestamp, #machine_id, #measurement_type_id, #point_of_measurement_id)", connection);
addMeasurementQuery.Parameters.AddWithValue("#value", value);
addMeasurementQuery.Parameters.AddWithValue("#timestamp", timestamp.ToString("YYYY-MM-DD HH:MI:SS:MS"));
addMeasurementQuery.Parameters.AddWithValue("#machine_id", fk_machineID);
addMeasurementQuery.Parameters.AddWithValue("#measurement_type_id", fk_pointOfMeasurementID);
addMeasurementQuery.Parameters.AddWithValue("#point_of_measurement_id", fk_measurementTypeID);
addMeasurementQuery.ExecuteNonQuery();
Can someone give a push into the right direction to solve this issue? I think i might format the timestamp incorrect but im not sure.
After some more research about this issue i found the following solution:
I tried what Dan said in the comments but couldnt get it to work.
NpgsqlCommand addMeasurementQuery = new NpgsqlCommand("INSERT INTO verbruggen_iot.measurement_ms (value, timestamp, machine_id, measurement_type_id, point_of_measurement_id) values(#value, CAST(#timestamp as timestamp), #machine_id, #measurement_type_id, #point_of_measurement_id)", connection);
The difference between the query in the question and this one is that i cast the timestamp the following way:
CAST(#timestamp as timestamp)
Using the cast above i'm stil able to execute the rest of my code.

Duplicate error after inserting rows in table which fields has INDEXED(DUPLICATES OK)

Here is my table. Two indexed columns with Indexed property set to Yes (Duplicates OK)
Just like that:
But when I'm trying to insert rows using this code in c# winforms, as follows:
string query = "INSERT INTO Complaints(SickLeaveId, ComplaintId) " +
"VALUES(14, 4)";
using (OleDbConnection connection = new OleDbConnection(connectionString))
using (OleDbCommand command = new OleDbCommand(query, connection))
{
connection.Open();
command.ExecuteNonQuery();
}
}
I get the following:
System.Data.OleDb.OleDbException: 'The changes you requested to the table were not successful because they would create duplicate values in the index, primary key, or relationship. Change the data in the field or fields that contain duplicate data, remove the index, or redefine the index to permit duplicate entries and try again.'
I would really appreciate your help!
I have just tried to create a table like yours and I have set the two columns with two NON UNIQUE indexes. One on the first column and one on the second column.
No other indexes or primary key defined. In this context your code has no problem in inserting many identical records. So the problem is somewhere else in the definition of your table
I suppose that you have a primary key defined on the table.
This automatically create an unique index and thus you cannot insert duplicates in that column or in the columns set that define the primary key
According to the exception You violate index or primary key of the table
So Try to Generate Creation script of the table to ensure of all constrains on the table.

Update/Insert rows in SQL table with encrypted columns using LinqToSQL - Always Encrypt

I am trying to get a hands-on on Always Encrypt feature of SQL Server 2016. I am using an existing application and database to do this.
I have a table [User], where i have encrypted the 'Password' column with 'Deterministic' type. I have made the connection string changes and I am able to retrieve all the rows. I have created the repository for this table.
I am trying to insert and update rows in this table with LinqToSQL using InsertOnSubmit() and SubmitChanges().
But whenever I try to insert new rows or update existing rows, I get the error:
Msg 206, Level 16, State 2, Line 7 Operand type clash: varchar is
incompatible with varchar(20) encrypted with (encryption_type =
'DETERMINISTIC', encryption_algorithm_name =
'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name =
'CEK_Auto1', column_encryption_key_database_name = 'BRO_UAT')
collation_name = 'Latin1_General_BIN2'
I have read articles where using Stored Procs and parameterization has solved the issue. But, as I mentioned earlier, this is an existing project, and I have used LinqToSql and do not want to change the code. Insertion/Update works fine if the column is not encrypted!
Am I missing some setting?Please point me towards the right direction.
Change your column to nvarchar and check.
Also now even storing the password is not the best approach, store a signature instead and validate that signature when validating the password.
Check the link for the same.
https://social.msdn.microsoft.com/Forums/en-US/77bb69f0-590e-40f5-b5e9-714bf590e008/how-to-handle-encrypted-column?forum=linqtosql

Value Insert error in LINQ/C# for Column identity

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.

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