Domanda

I have the following problem. I pass values as XML like string and I'm not passing defaults such as false or 0 for numerical columns. So, I create a Dictionary where key is the column name and value is the passed value.

This is my current code

foreach (KeyValuePair<String, String> kvp in rowValues)
     {
        String passedValue = kvp.Value.Trim();
        String rowValue = bookingRow[kvp.Key].ToString().Trim();
        if (passedValue != rowValue)
        {
           // code here
        }
     }

The problem is with default values. I can see by debugging my test case that the passedValue is empty and the rowValue is 0 (the column is integer type). So, my question is - how should I re-write the code above to properly convert my passed value into the type of the column. In other words, instead of converting them both to string I need to convert passed value into correct type of DataRow column.

Sample of the passedValue - "".

Sample of the rowValue = " " (empty string with the length of the column)

Or another example:

Sample of the passedValue = ""

Corresponding rowValue = 0 (the value is Integer in the table)

Both cases should be treated as the same value - no need to write into history.

Thanks to the answers, I am now testing this code:

String passedValue = kvp.Value.Trim();
        var rowValue = bookingRow[kvp.Key];
        if (Convert.ChangeType(passedValue, rowValue.GetType()) != rowValue)
        {
           String rowValueString = rowValue.ToString().Trim();
           if (rowValueString!=passedValue) // Double check to prevent cases of "" vs. "          "
              this.SaveToBookingHistory(booking_id, "M", kvp.Key, rowValueString, passedValue, ref messageText, ref statusCode);
        }
È stato utile?

Soluzione

I don't have all your code, so this might not be exactly correct; but you should be able to do something like this...

foreach (KeyValuePair<String, String> kvp in rowValues)
{
    var rowValue = bookingRow[kvp.Key];
    var passedValue = Convert.ChangeType(kvp.Value.Trim(), bookingRow[kvp.Key].GetType());
    // or, if your bookingRow comes from a table
    var passedValue = Convert.ChangeType(kvp.Value.Trim(), table.Columns[kvp.Key].DataType);
    if (passedValue.Equals(rowValue) == false)
    {
        // code here
    }
}

Edit: You are going to have some issues with this. You need to use the .Equals method (I've changed the code above), because ChangeType returns an object; and != does a reference comparison. This will take care of cases where the rowValue is 0 and the passedValue is 0 boxed as an object.

However, this will not address cases where you have "" and " ". Those two things are not the same, and they are not equal; and, you don't know without inspecting the values that they are strings. So, I would suggest you write some sort of functions to perform the comparisons manually.

Altri suggerimenti

I got the solution in UniversalThread.com forum by Rob Jasinski. This is my final code

if (bookingRow.Table.Columns.Contains(kvp.Key))
        {
           String passedValue = kvp.Value;
           var columnValue = bookingRow[kvp.Key];
           Type columnType = bookingRow[kvp.Key].GetType();

           //var passedObject = Convert.ChangeType(passedValue, columnType);
           if (!passedValue.StringEquals(columnValue, columnType))
           {
              String cColumnValue = columnValue.ToString().Trim();
              if (cColumnValue != passedValue) // Double check to prevent cases of "" vs. "          "
                 this.SaveToBookingHistory(booking_id, "M", kvp.Key, cColumnValue, passedValue, ref messageText, ref statusCode);
           }
        }

and I also added the following StringEquals extension method:

/// <summary>
  /// returns default value for the passed type
  /// / See http://stackoverflow.com/questions/325426/programmatic-equivalent-of-defaulttype
  /// </summary>
  /// <param name="t"></param>
  /// <returns></returns>
  public static object GetDefault(Type t)
  {
     if (t.IsValueType)
     {
        return Activator.CreateInstance(t);
     }
     return null;
  }

  /// <summary>
  /// Compare string with object (Rob Jasinski)
  /// </summary>
  /// <param name="stringValue"></param>
  /// <param name="objectValue"></param>
  /// <param name="objectType"></param>
  /// <returns></returns>
  public static bool StringEquals(this String stringValue, object objectValue, Type objectType)
  {
     object convertedStringValue = GetDefault(objectType);
     if (!string.IsNullOrWhiteSpace(stringValue))
        convertedStringValue = Convert.ChangeType(stringValue, objectType);

     return object.Equals(convertedStringValue, objectValue);
  }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top