DataTable.Select - Thread.CurrentThread.CurrentCulture - String.Format

R

Rainer Queck

Hi NG,

in my application a <myDataTable>.Select fails with "Syntax error in the
expression."
It took me a while, isolate the cause to this:

To select some datarows from a data table I am using a select sting like
"selectStr = String.Format("x >= {0}", aDoubleVar)".
The Thread.CurrentThread.CurrenCulture is set to "en-US" where the
Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator is
a '.' as expected. BUT.... debugging my selectStr it turned out to be "x>=
2,14" !

After a while I had the Idea to check ControlPanel->Regional and
LanguageOptions and YES, the user has changed the decimal seperator.

So I currently looks like
- String.Format uses the ControlPanel Settings ","
- The DataTable uses Thread.CurrentThread.CurrentCulture "."

Is this a BUG in the Framework, or in my HEAD? Is there something I missed?
Any help or hint on this subject is very appreciated.

Regards
Rainer Queck
 
M

Marc Gravell

I don't know much about DataTable(I've always steered fairly clear of
DataSet), but if this was a regular SqlCommand (etc) I would be adding
a parameter with .Value = aDoubleVar - that way, you don't need to
worry about formatting, plus it is injection safe (think "Bobby
Tables"...).

However, if you /must/ use string concatenation, then you should
ensure that the format is in the known, fixed, expected format of
whatever you are talking to. It is *entirely reasonable* for the user
to use their local (or /locale/) formats and separators, and your code
shouldn't rely on this. This should be used for displaying data to the
user, not exchanging data between systems. You could try passing
CultureInfo.InvariantCulture as the first argument to string.Format
(although you might need a more specific format...).

But I stress; the most reliable option is using parameters.

This is a /similar/ (but unrelated) problem to using the default
encoding / endianness when exchanging text as binary; when talking
between systems it is best to agree in advance what formats to use.

Marc
 
R

Rainer Queck

Hello Marc,

thanks for helping me again!

Marc Gravell said:
I don't know much about DataTable(I've always steered fairly clear of
DataSet), but if this was a regular SqlCommand (etc) I would be adding
a parameter with .Value = aDoubleVar - that way, you don't need to
worry about formatting, plus it is injection safe (think "Bobby
Tables"...).
Yes, it would be preferable to use aDoubleVar parameter. Unfortunately in
order to do a select ( which is not a regualr SqlCommand ) on a dataTable
(see DataTable.Select) I must use a string, unless there I a feature in
DataTable I havn't met yet.
However, if you /must/ use string concatenation, then you should
ensure that the format is in the known, fixed, expected format of
<snip>
Well, the word "expected" in my question results of the information I
retreave from Thread.CurrentThread.CurrentCulture (en-US at that time) as I
set the breakpoint at the codeline in question. I in the meanwhile also
looked at
"Thread.CurrentThread.CurrentCulture.Numberformat.CurrentDecimalSeperator"
which also showed ".". Still the String.Format gave me a "," !

whatever you are talking to. It is *entirely reasonable* for the user
to use their local (or /locale/) formats and separators, and your code
shouldn't rely on this. This should be used for displaying data to the
user, not exchanging data between systems. You could try passing
CultureInfo.InvariantCulture as the first argument to string.Format
(although you might need a more specific format...).
That "sounds" like a solution. I am a little hesitant, because (what I have
not mentioned yet) on of the requirements to my application is, that the
used language must be changable at runtime. Also it is a multithreaded
application (might be, that I still have some lacks here).

Would it be ok to only set Thread.CurrentThread.CurrentUICulture to what
ever the user wants and have the Thread.CurrentThread.CurrentCulture
internaly set to CultureInfo.InvariantCulture? Would this also work if
Parameters entered by the user in his Culture are processed by methods where
their thread is set to InvariantCulture?

Regards
Rainer
 
R

Rainer Queck

Hi Marc,
You could try passing
CultureInfo.InvariantCulture as the first argument to string.Format
(although you might need a more specific format...).
What kind of a Culture is a DataTable using for example on a select? Is it
possible, that it usese the "InvariantCulture" as well?
If that is the case, I could get rid of my problem by following your
suggestion. If not.... :-(

Regards
Rainer
 
M

Marc Gravell

I wouldn't set the culture the invariant - I'd (as indicated) *use*
the invariant culture when I am doing system-to-system calls - i.e.
string.Format(CultureInfo.InvariantCulture, "foo", bar).

Note that there can be issues messing with culture while forms are
displayed; they don't like that much... a simpler option might be to
save the new culture in a settings file, and restart the app? (I
believe that Application has a Restart method or similar).

Also; re supplying proper parameters - I don't really know (not having
done it myself), but is this not the GetFillParameters method on the
data-adapter?

Marc
 
R

Rainer Queck

Hi Mark,

Marc Gravell said:
I wouldn't set the culture the invariant - I'd (as indicated) *use*
the invariant culture when I am doing system-to-system calls - i.e.
string.Format(CultureInfo.InvariantCulture, "foo", bar).
Yes, that is what I am currently doing (ref my other answer/question).
Note that there can be issues messing with culture while forms are
displayed; they don't like that much... a simpler option might be to
save the new culture in a settings file, and restart the app? (I
believe that Application has a Restart method or similar).
It surely would be better, to set the culture and the stop/restart the
application. Unfortunately it is a request from my customer, that the app
must be able to switch rultures at runtime. Acutally this is working quite
good. I used the method pointed out in
http://dzaebel.net/LocalizeRuntime.htm by Frank Dzaeble.
Also; re supplying proper parameters - I don't really know (not having
done it myself), but is this not the GetFillParameters method on the
data-adapter?
You are right, but I dont have a data-adapter, since I am working with a
"standalone" typed DataSet.

As mentioned above, I am already following your suggestion, and am using
CultureInfo.InvariantCulture to do my String.Format on selectStr generation.
It seems to be working fine, which leads me to the thought, that DataSets
are using CultureInfo.InvariantCulture internaly as well.
If someone could state this true, I can replace "seems to" with "is" ;-)

Regards
Rainer
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top