Strange issue about double numbers with commas - c#

I have a field in db named 'loss' which is of type float.
Here is how I save it in db:
[HttpPost]
public int SaveLoss(float loss)
{
var t = (from x in db.tblTest
where x.id == 8
select x).First();
t.loss = loss; //also tried t.loss = loss / 1;
db.SaveChanges(); //entity framework
}
This is how I always work and in all the other tables it works fine.
I enter the loss via a textbox and here is the Ajax call:
$.ajax({
type: "POST",
url: "/Test/SaveLoss",
data: {
loss: parseFloat($('#myTextbox').val().replace(',', '.'))
}
....
If in the textbox I enter 66.55, everything works great. If in the textbox I enter 66,55, the value stored in db is 6655. This issue doesn't happen on my computer. When I publish the application on server, it occurs. Why is this annoying issue happening and how to fix it?
Fiddler says that 66.55 is input parameter of SaveLoss.

It looks like either the browser or server has a different number format, perhaps it is running in a culture where ',' is used as a decimal separator and '.' as a thousands separator.
You could try setting Thread.CurrentThread.CurrentCulture to CultureInfo.InvariantCulture after starting the server or before running the database query.

If You have generated EF mapping using database first. You should be concerned about EntityFramework..
EF maps SQL column type float into C# type double not float
see: SqlClient for Entity FrameworkTypes

Pass it as string and try like this while saving in entity framework:
var amount = decimal.Parse(InvoiceAmount, NumberStyles.Any);

Related

Oracle .NET appending M for ExecuteScalar int values. VS2019 reports only int in tooltip

I have an application that takes user created COUNT(*) query and does a cmd.ExecuteScalar() and notifies users based on the result.
This is utilizes both SQL and Oracle .NET adapters.
Using SQL adapters this code block runs as expected for returned int values:
var threshold = await command.ExecuteScalarAsync();
if (threshold is int?)
//Continue with int comparison logic
However, using Oracle adapters if(threshold is int?) returns false. If we look at the tooltips in VS2019 you would not know anything is wrong.
Clicking into the value you can see the actual issue is that Oracle returns an M on the value:
My issue is two-fold:
Why does .NET Oracle adapters append an M to the end of the values being returned from ExecuteScalar?
Why doesn't VS2019 show the true values in tooltips?
EDIT:
The following solves the coding issue:
var scalarResult = await cmd.ExecuteScalarAsync();
if (int.TryParse(scalarResult.ToString(), out int threshold))
Wish in the hover over tooltip it showed 0M or the datatype of the zero without having to "edit" the value to see its "true value".
The issue is exactly as #astentx stated in your question. Int is C#. You want to reference Oracle.DataAccess.dll (or ManagedDataAccess) and use the appropriate data type from OracleDbType. Since COUNT is only going to return an integer, INT32 or INT64 is probably the best option since there is no NUMBER type.
Even though the above should work, my preference is usually to pull numbers back into C# as strings to avoid the data conversion and then use MS libraries to convert them to numbers natively. This does require that you lock down your user queries to either have the user define the data type returned or you programmatically lock it as always being a certain type, such as number in this case.

Ignore DATETIME fields in MySqlDataAdapter.Update(DataTable)?

I have an app which worked fine with Sql Server. I have a DevExpress grid which shows just a record in carousel mode (not that this matters, I hope).
Now, I have changed the code to be database-agnostic and I'm testing MySql. When the user modified the record and accepted the changes, I was getting the following error:
Concurrency violation: the UpdateCommand affected 0 of the expected 1
records
After some research, I've come to the conclussion that the problem lies in DATETIME fields. I am using "Allow Zero Datetime=False; Convert Zero Datetime=True;" in my MySql connection string so I can convert default DATETIME values to .Net DateTime objects. The autogenerated UpdateCommand includes every field in the where clause, and I guess the comparison fails when the MySql DATETIMEs are set to the default value, as removing DATETIME fields the problem went away.
I have a Primary Key column, and the user isn't allowed to modify it, so what's the right way to issue a custom UpdateCommand so that there's only one field in the WHERE clause?
My current code for accepting changes:
Dim builder As DbCommandBuilder = m_Conn.CreateCommandBuilder(m_Adapter)
m_Adapter.Update(m_DataTable)
CreateCommandBuilder is an extension method on IDbConnection to create the correct an object with a correct implementatin of the DbCommandBuilder interface.
Your DBCommandBuilder should have a ConflictOption Property that needs to be set.
Presumably you want to set it to ConflictOption.OverwriteChanges.
I'm not sure if it works when you initialize the Adapter commands via the CommandBuilder Constructor but a
var builder = new MySqlCommandBuilder();
builder.ConflictOption = ConflictOption.OverwriteChanges;
builder.DataAdapter = m_Adapter;
should do.
Instead of using "Allow Zero Datetime=False; Convert Zero Datetime=True;" in your connection string (which FYI I'm not familiar with), I'd recommend using DateTime.Parse(value). You'll probably want to write a function so that you can easily handle nulls as well.
private DateTime getDateTimeField(string dbValue)
{
if (dbValue == null)
{
return new DateTime();
}
else {
return DateTime.Parse(dbValue);
}
}

Sqlite-net guid select returns empty guid

I'm developing a Windows Store App with sqlite as database. I'm using SQLite for Windows Runtime and sqlite-net. Trying to get a list of Guid from a table, but only getting empty guids in the list ({00000000-0000-0000-0000-000000000000}). However when querying only for one guid it works as it should be.
My code is the following:
async void SyncSurveys()
{
SQLiteConnection _db = new SQLiteConnection(Path.Combine(ApplicationData.Current.LocalFolder.Path, "SurveyDB"));
var localSurveys = (from s in _db.Table<Survey>()
select s.SurveyGuid).ToList();
...
}
I've tried the query in the following format also, but it is neither works:
var localSurveys = _db.Table<Survey>().Select(s => s.SurveyGuid).ToList();
But if I'm using the following query, to get only one guid just for debug purpose it works well:
var localSurvey = db.Table<Survey>().FirstOrDefault().SurveyGuid;
In the not working scenario the list's count matches the table's rowcount. Does anyone have any idea why this isn't working with the list version?
This isn't an answer, but it might put you down the right path. I noticed there is an option that can be added to a connection string that sets if GUIDS are stored in binary or not
Data Source=c:\mydb.db;Version=3;BinaryGUID=False;
More info https://www.connectionstrings.com/sqlite/
I think the problem should be the basic script commands are properly written.
It may be a bug database.

inserting c# double values to sql server float field. (no fractional part)

I am trying to insert double values to my database via EF 5. I generated EF entity model from db. There is a price column in the table which is float, and naturally EF generated a double type for the mapper class.
I read some string values from a file and convert it to double and save it to db. When I debug I can see that values are converted correctly. For example string value "120,53" is converted to double like 120.53, just fine. But when I save my context it goes to db like "12053".
What can cause such a problem? Is there any setting in SQL Server has anything to do with this?
I believe the problem is in your Convert.ToDouble and the , being used instead of a decimal. Without supplying the culture for the number it's likely instead interpreting the , as a thousandths separator and ignoring it. Try passing in CultureInfo.CurrentCulture as the second argument (IFormatProvider) if the culture of your environment is one where the , is used as a decimal. Or, since it looks like you're replacing a decimal with the , - just don't replace it.

MySQLConversionException Problem in C#

I am currently developing a C# MySQL Export Utility. Due to this I am not going to know the fields or the data types of each field in the table.
When I export the data from the table in the database it displays a MySQLConversionException stating that it is unable to Covert MySQL Date/Time to System.DateTime. It was doing this when I ran the code:
if (!reader.isDBNull(fieldCount)){}
However, when the exception was thrown on this line I fixed it by adding Allow Zero DateTime=true to the MySQL Connection string but not it is displaying the error when I run the code
string value = reader.getString(field);
How can I get around this issue bearing in mind I am not going to know what data type is or what the value is going to be.
Thanks for any help you can provide.
You can get the raw value as object:
object value = reader[field];
Then decide what to do based on its type:
if (value is string)
{
string sVal = value.ToString();
//handle as string...
}
else if (value is DateTime)
{
DateTime dtVal = (DateTime)value;
//handle as DateTime...
}
else
{
//some other type
}
Maybe not elegant, but should work.
If you read DATETIME values with MySQL Connector/Net and set 'Allow Zero Datetime', then you should use the reader.GetValue() method; in this case the reader will return a MySqlDateTime object with '0000-00-00 00:00:00' value.
Connector/Net Connection String Options Reference
Note, than .NET DateTime.MinValue = 00:00:00.0000000, January 1, 0001.
Also, try dotConnect for MySQL components.
I tackled a problem similar to this in an old open source project of mine. See it here in my Util.DefaultConvert() method.
The trick is to use Type.GetTypeCode() and switch on the result.
Then implement a strict conversion for each type. There is most likely other code in there you can check out to do what you need. I have a MySql provider in there as well.

Categories

Resources