NpgSql's AddWithValue does its best to map the datatype of the C# property to the PostgreSQL field's datatype, but the issue is that PostgreSQL has two primary datatypes for date:
date
timestamp
But C# has just the one -- System.DateTime. So even the .Date Property of a DateTime object yields a DateTime type.
In other words, NpgSql has to make a choice -- and it renders the PostgreSQL datatype as a timestamp. If your DB type is actually a date, the execution will fail due to datatype mismatch.
For strings, integers, decimals and doubles AddWithValue always seems to work exactly as expected, but if your date is a [PostgreSQL] DATE then you need to be explicit with your parameter declaration's datatype. In general, this is a good practice anyway:
cmd.Parameters.Add(new NpgsqlParameter("@birth_date", NpgsqlTypes.NpgsqlDbType.Date));
cmd.Parameters[0].Value = cliente.BirthDate;
This is definitely advantageous over AddWithValue if you are doing multiple transactions like this:
cmd.Parameters.Add(new NpgsqlParameter("@birth_date", NpgsqlTypes.NpgsqlDbType.Date));
cmd.Parameters.Add(new NpgsqlParameter("@user_id", NpgsqlTypes.NpgsqlDbType.Integer));
foreach (User u in Users)
{
cmd.Parameters[0].Value = u.Birthday;
cmd.Parameters[1].Value = u.UserId;
cmd.ExecuteNonQuery();
}
For a single query or transaction, you can also use the Shorthand:
cmd.Parameters.Add(new NpgsqlParameter("@birth_date", NpgsqlTypes.NpgsqlDbType.Date)).
Value = cliente.BirthDate;
As a final alternative, you can "fix" the dbtype after the fact:
cmd.Parameters.AddWithValue("@birth_date", cliente.BirthDate);
cmd.Parameters[0].NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Date;
I don't think that's any easier than the other options, but it is an option that will work.