user3021830
user3021830

Reputation: 2924

I need to make linq to run depending on the value is floating point or not

I am using XDocument to make search on large XML files. When a user seeks a numeric value I get the value as decimal, I do not differentiate between integers and floating point values. I know that assuming that the input from XML as a decimal is faulty but can not build a shorthand logic without writing extensive code.

User enters the value to seek on form as decimal and I save all filter values as a property by boxing in my SearchCriteria object. Then I use the following code to find matching elements:

IEnumerable<XElement> allNodes = xDoc.Root.Descendants(root);
allNodes = (from ex in allNodes 
    where ex.Descendants(fieldName)
        .Where(x => decimal.Parse(x.Value.Replace(".", ",")) == decimal.Parse(crit.SearchValue.ToString()))
        .Count() > 0 
    select ex);

and get an exception for fields such as postal code, because it does not contain any decimal points.

What I want to do is to make search all values regardless of they contain a decimal point in it or not. But to accomplish this task I need to have a logic to decide whether to replace decimal point before comparison or not.

How can I do it in LinQ?

Regards.

Upvotes: 0

Views: 82

Answers (2)

Yoh Deadfall
Yoh Deadfall

Reputation: 2781

Just rewrite condition:

ex
   .Descendants(fieldName)
   .Where(x => {
      decimal dec;
      return
         decimal.TryParse(x.Value, NumberStyles.Number, culture, out dec) &&
         /* other conditions and comparison with dec */;
}

If value cann't be parsed it's ignored.

EDIT: Use specific culture to parse numbers. It will be faster and will consume less memory. Also store parsed crit.SearchValue outside of the lambda.

Upvotes: 2

Roy Dictus
Roy Dictus

Reputation: 33149

There is no need to replace a "." by a ",". You can query for decimal.Parse(s,NumberStyles.Any, new CultureInfo("en") and it will work.

You can make the code much more efficient by taking repeated stuff out that doesn't need to be repeated:

IEnumerable<XElement> allNodes = xDoc.Root.Descendants(root);
decimal match = decimal.Parse(crit.SearchValue.ToString());
CultureInfo culture = new CultureInfo("en");
allNodes = (from ex in allNodes where ex.Descendants(fieldName)
    .Where(x => decimal.Parse(x.Value, culture) == match)
    .Count() > 0 select ex);

Upvotes: 3

Related Questions