1

我有以下问题。我将值作为 XML 之类的字符串传递,并且我没有为数值列传递默认值,例如 false 或 0。所以,我创建了一个字典,其中键是列名,值是传递的值。

这是我当前的代码

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

问题在于默认值。通过调试我的测试用例可以看到,passedValue 为空,rowValue 为 0(列为整数类型)。所以,我的问题是 - 我应该如何重新编写上面的代码以正确地将我传递的值转换为列的类型。换句话说,我需要将传递的值转换为正确类型的 DataRow 列,而不是将它们都转换为字符串。

传递值的样本 - “”。

rowValue = "" 的示例(列的长度为空字符串)

或者另一个例子:

传递值示例 = ""

对应rowValue = 0(表中值为Integer)

两种情况都应视为相同的值-无需写入历史记录。

感谢答案,我现在正在测试这段代码:

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);
        }
4

2 回答 2

5

我没有你所有的代码,所以这可能不完全正确;但你应该能够做这样的事情......

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
    }
}

编辑:你会有一些问题。您需要使用 .Equals 方法(我已经更改了上面的代码),因为 ChangeType 返回一个对象;和 != 进行参考比较。这将处理 rowValue 为 0 且passedValue 为 0 的情况,将其装箱为对象。

但是,这不会解决您有“”和“”的情况。这两个东西不一样,也不相等;而且,如果不检查它们是字符串的值,您就不会知道。因此,我建议您编写某种函数来手动执行比较。

于 2013-07-09T21:45:40.487 回答
0

我在 Rob Jasinski 的 UniversalThread.com 论坛上得到了解决方案。这是我的最终代码

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);
           }
        }

我还添加了以下 StringEquals 扩展方法:

/// <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);
  }
于 2013-07-10T20:11:44.160 回答