【问题标题】:Nullable object must have value Exception可空对象必须有值异常
【发布时间】:2013-03-10 07:45:44
【问题描述】:

我是 CRM 2011 插件的新手。我写了一个插件来更新税值。但是在下面的行它会抛出错误

“可空对象必须有值”

double Tax = (double)(QuoteProduct.BaseAmount - QuoteProduct.ManualDiscountAmount - 
             QuoteProduct.VolumeDiscountAmount) / 20;

发生错误时,值为: 基础金额 = 0,
手动折扣金额 = null,
批量折扣金额 = 0

【问题讨论】:

  • 声明更多,在发生错误的级别值为:基础金额= 0,手动折扣金额= null,批量折扣金额= 0
  • 检查 GetValueOrDefault 方法
  • 当一个金额是null 时,您预计要交多少税?你想用零代替null吗?或者你希望你的结果是null
  • 我希望结果为零。
  • BaseAmountManualDiscountAmountVolumeDiscountAmount的类型有哪些?它们都可以为空吗double (double?)?

标签: c# plugins dynamics-crm-2011


【解决方案1】:

假设您的所有变量都是Nullable<T> 类型,您可以使用GetValueOrDefault() 方法(MSDN 文章)。

该方法将返回对象具有的值,或者在 null 的情况下返回该类型的默认值(0.0 表示双精度)。

double Tax = (double)(QuoteProduct.BaseAmount.GetValueOrDefault() - QuoteProduct.ManualDiscountAmount.GetValueOrDefault() - 
             QuoteProduct.VolumeDiscountAmount.GetValueOrDefault()) / 20;

【讨论】:

  • 感谢您的回复。我使用了你的方法,但它在 savechanges 行抛出异常: var QuoteProduct = crm.QuoteDetailSet.Where(c => c.QuoteDetailId == QPID).First();双税 = (double)((QuoteProduct.BaseAmount - QuoteProduct.ManualDiscountAmount.GetValueOrDefault() - QuoteProduct.VolumeDiscountAmount.GetValueOrDefault()) / 20); QuoteProduct.Attributes["tax"] = 税; crm.UpdateObject(QuoteProduct); crm.SaveChanges();
  • 请分享异常的详细信息 - 或者问一个单独的问题,以便更多人可以提供帮助
  • 也可以用(QuoteProduct.BaseAmount ?? 0.0)代替QuoteProduct.BaseAmount.GetValueOrDefault()。但是在使用 ?? 运算符时要小心括号,例如减号(二进制 - 运算符)。
  • @KonradViltersten:en.csharp-online.net/…。它就在条件运算符之上
  • @KonradViltersten 是的,但你必须用一些括号来更新你自己的答案。
【解决方案2】:

您不能将 null 强制转换为 double。

double x = null;

产生错误:

无法将 null 转换为 'double',因为它是不可为空的值类型

所以你必须确保你的值是 0(零)而不是 null。

【讨论】:

  • 这是 CRM。大多数值都可以为空,因此在大多数情况下为double? x = null;。或者更确切地说是decimal? x = null;.
  • CRM 与否:他试图双重征税 = (double)(null);这在 C# 中不起作用。
  • 正确。我的意思是在这种特殊情况下的更正应该将 double 更改为 double?null 值是正确的。接收变量的类型错误。所以我没有纠正你 - 而是延长你的回复。
【解决方案3】:

你不能从 null 中减去!

if (... != null) 

【讨论】:

    【解决方案4】:

    我从您发表的另一篇文章中认出了这个表述。通常,在这种情况下,我会使用如下很好的语法。 (其他回复者提到的 GetValueOrDefault 语法是可以的,但往往会使您的代码可读性降低,并且行 waaay 会变长。)

    考虑以下更改(我假设每个部分都可能碰巧为 null

    decimal tax = QuoteProduct.BaseAmount ?? 0;
    tax -= QuoteProduct.ManualDiscountAmount ?? 0;
    tax -= QuoteProduct.VolumeDiscountAmount ?? 0;
    QuoteProduct.Attribute["tax"] = tax / 20;
    

    (我假设这与your other question有关。)

    【讨论】:

    • 如果金额可以为空double,则tax 必须是double(而不是decimal)。否则我喜欢使用?? 运算符。
    • @JeppeStigNielsen 正确。但我相当肯定他的值是十进制,如果不是Money。在我看来,CRM 有点倒退。我喜欢你的挑剔。让我无法在示例中提供某种工作代码。谢谢!
    猜你喜欢
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多