сравнивая деньги в sql server с десятичной в C # - PullRequest
0 голосов
/ 14 ноября 2011

У меня есть несколько полей в db с типом money, а в C # я использовал для них десятичную. Я сравниваю значения в C # cоде так:

public static string CompareValues(DbPropertyValues currentValues, DbPropertyValues DbValues)
        {
            string result = string.Empty;

            foreach (var currentPropertyName in currentValues.PropertyNames)
            {
                foreach (var DBPropertyName in DbValues.PropertyNames)
                {
                    if (DBPropertyName == "PropertyCreditLimit" || DBPropertyName == "PropertyCreditLimit" || DBPropertyName == "PropertyCreditLimit" || DBPropertyName == "PropertyCreditLimit" || DBPropertyName == "PropertyCreditLimit")


                    if ((currentPropertyName == DBPropertyName))
                    {
                        if (( currentValues[currentPropertyName] != null && DbValues != null) &&  (currentValues[currentPropertyName].ToString() != DbValues[DBPropertyName].ToString()))
                        {
                            result += string.Format("Property{0}, {1} =  {2}, {3} <br />", currentPropertyName, DbValues[DBPropertyName], currentValues[currentPropertyName], DBPropertyName);
                        }
                    }
                }
            }

            return result;
        }

но оно не совпадает из-за количества нулей / точности:

PropertyDateFirstReported, 3/8/2008 1:15:36 AM = 1/1/0001 12:00:00 AM, DateFirstReported 
PropertyCreditLimit, 564000.0000 = 564000.00, CreditLimit 
PropertyBalance, 45.0000 = 45.00, Balance 
PropertyMinimumInstallment, 0.0000 = 0.00, MinimumInstallment 
PropertyTerm, = Term1, Term 
PropertyPurpose, a = a1, Purpose 
PropertyCollateralValue, 0.0000 = 0.00, CollateralValue 
PropertyAccountUniqueID, 3767 = 0, AccountUniqueID 
PropertyPayment, 564000.0000 = 564000.00, Payment

Как это исправить?

Ответы [ 5 ]

0 голосов
/ 14 ноября 2011

Не преобразовывать в строки для сравнения десятичных сумм; Нули, отступы, форматы, локализация, значащие цифры, десятичные разряды - все это может измениться во время выполнения. Вы устанавливаете мины в своем коде. Сделай это.

decimal? d1 = currentValues[currentPropertyName] as Nullable<decimal>;
decimal? d2 = (DbValues == null)? null : DbValues[DBPropertyName] as Nullable<decimal>;
if (d1 == d2)
    ...;
0 голосов
/ 14 ноября 2011

Попробуйте это:

if (!object.Equals(currentValues[currentPropertyName], DbValues[DBPropertyName]))
{
  //Do stuff
}

Примечания: object.Equals (null, null) считается истинным

0 голосов
/ 14 ноября 2011

Если вам нужно сравнить строки, используйте форматер 'f2', чтобы гарантировать 2 десятичных знака. В противном случае просто приведите значение DB к (decimal).

Возможно, что-то вроде этого:

bool isEqual = false;
if ( currentValues[currentPropertyName] != null && DbValues != null) {
 if (currentValues[currentPropertyName] is decimal && DbValues[DBPropertyName] is decimal) {
   isEqual = (Decimal)currentValues[currentPropertyName] == (Decimal)DbValues[DBPropertyName];
} else {
   isEqual = currentValues[currentPropertyName].ToString() == DbValues[DBPropertyName].ToString();
}

Вы можете добавить дополнительные операторы else, если найдете другие типы данных, где ToString() не дает правильного значения для сравнения. Или вы можете добавить их, чтобы вообще не звонить ToString().

0 голосов
/ 14 ноября 2011

Если вы собираетесь сравнивать их как строки, они вам понадобятся в том же формате, например,

.ToString ("F02", CultureInfo.InvariantCulture);

Почемуне конвертируете ли вы деньги в десятичную при чтении / записи из БД, вы будете с этим повсюду.

0 голосов
/ 14 ноября 2011
 (currentValues[currentPropertyName].ToString() != DbValues[DBPropertyName].ToString()

В настоящее время вы сравниваете их как строки , что объясняет, почему нет совпадений - вместо этого вы должны сравнить значения.

...