1

使用以下代码:

foreach (JObject obj in arr)
{
    id = (string)obj["Id"];
    packSize = (Int16)obj["PackSize"];
    var description = (string)obj["Description"];
    var deptSubdept = (Double)obj["DeptDotSubdept"];
    var unitCost = (Double)obj["Unit_Cost"];
    var unitList = (Double)obj["Unit_List"];
    var UPC_Code = (string)obj["UPC_code"];
    var UPC_packSize = (Int16)obj["UPC_pack_size"];
    var CRVId = (Int32)obj["CRV_Id"];

inventoryItems.Add(new WebAPIClientUtils.InventoryItem
{
    Id = id,
    PackSize = packSize,
    Description = description,
    DeptDotSubdept = deptSubdept,
    Unit_Cost = unitCost,
    Unit_List = unitList,
    UPC_code = UPC_Code,
    UPC_pack_size = UPC_packSize,
    CRV_Id = CRVId
});

...我得到,“ System.ArgumentException:输入字符串的格式不正确。无法将 <> 存储在成本列中。预期类型为 Double。---> System.FormatException ...

注意:“成本”是本地表中以这种方式定义的列的名称:

// Create temp table that mirrors InventoryItems as a staging area for the data to be bulk copied
var dt = new DataTable();
dt.Columns.Add(new DataColumn("Id", typeof(string)));
. . .
dt.Columns.Add(new DataColumn("Cost", typeof(double)));
. . .

因此,当检索到的数据具有这些虚假/空值时,我如何检查并使用诸如 0.00 表示双精度值、0 表示 int、string.empty 表示 String 等值?

要查看何时发生这种情况,我在这一行放置了一个条件断点:

var unitCost = (Double)obj["Unit_Cost"];

...通过在断点条件对话框中输入以下内容:

unitCost.ToString() == ""

...但它永远无法达到。我还尝试将“ unitCost == null ”设置为条件断点,结果相同。

更新

有了这个:

id = (string)obj["Id"] ?? string.Empty;
packSize = (Int16)obj["PackSize"] ?? 0;
var description = (string)obj["Description"] ?? string.Empty;
var deptSubdept = (Double)obj["DeptDotSubdept"] ?? 0.0;
var unitCost = (Double)obj["Unit_Cost"] ?? 0.0;
var unitList = (Double)obj["Unit_List"] ?? 0.0;
var UPC_Code = (string)obj["UPC_code"] ?? string.Empty;
var UPC_packSize = (Int16)obj["UPC_pack_size"] ?? 0;
var CRVId = (Int32)obj["CRV_Id"] ?? 0;

...我得到:

操作员 '??' 不能应用于'short'和'int'运算符'??'类型的操作数 不能应用于'double'和'double'运算符'??'类型的操作数 不能应用于“int”和“int”类型的操作数

更新 2

我试过这个:

double unitCost;
if (obj["Unit_Cost"] != DBNull.Value)
{
    unitCost = (Double) obj["Unit_Cost"];
}
else
{
    unitCost = 0.0;
}

...并得到,“运算符'!='不能应用于'Newtonsoft.Json.Linq.JToken'和'System.DBNull'类型的操作数

更新 3

将条件赋值的初始部分包含在括号中,如下所示:

var UPC_Code = ((string)obj["UPC_code"]) ?? string.Empty;

...仅适用于字符串;我仍然得到其他数据类型(int 和 double)的错误消息。

更新 4

此代码中发生了运行时异常:

dt.Rows.Add(invItem.Id, invItem.PackSize, invItem.Description, invItem.DeptDotSubdept,  
    invItem.Unit_Cost, invItem.Unit_List, invItem.UPC_code, invItem.UPC_pack_size, 
    invItem.CRV_Id);

...所以我尝试了这个:

int packSize = 1;
double unitCost = 0.0;
double unitList = 0.0;

if (invItem.PackSize != null)
{
    packSize = invItem.PackSize;
}
if (invItem.Unit_Cost != null)
{
    unitCost = invItem.Unit_Cost;
}
if (invItem.Unit_List != null)
{
    unitList = invItem.Unit_List;
}

dt.Rows.Add(invItem.Id, packSize, invItem.Description, 
    invItem.DeptDotSubdept, unitCost, unitList, invItem.UPC_code, 
    invItem.UPC_pack_size, invItem.CRV_Id);

...但它仍然失败,并且“!= null”行在编辑器中有蓝色波浪线的情况。

更新 5

至于 SLaks 的建议,我试过:

if (obj["Unit_Cost"] == DBNull.Value)
{
    unitCost = 0.0;
}
else
{
    unitCost = (Double)obj["Unit_Cost"];
}

...但是得到,“运算符'=='不能应用于'Newtonsoft.Json.Linq.JToken'和'System.DBNull'类型的操作数

我对此也有同样的看法:

if ((Double)obj["Unit_Cost"] == DBNull.Value)

....和这个:

if (((Double)obj["Unit_Cost"]) == DBNull.Value)

更新 6

我看到当这失败时,unitCost 的值不是 null,而是 0。所以,我设置了一个断点来分配该值:

unitCost == 0

...但是断点被击中,即使该值为 0.0(这很好)。我认为即使是 0 也可以,但是......它失败了,所以这个值显然有问题。

4

6 回答 6

1

尝试使用运算符转换为可为空的类型as并使用Nullable(T).GetValueOrDefault.

foreach (JObject obj in arr)
{
    var id = obj["Id"] as string;
    var packSize = obj["PackSize"] as short?;
    var description = obj["Description"] as string;
    var deptSubdept = obj["DeptDotSubdept"] as double?;
    var unitCost = obj["Unit_Cost"] as decimal?;
    var unitList = obj["Unit_List"] as decimal?;
    var UPC_Code = obj["UPC_code"] as string;
    var UPC_packSize = obj["UPC_pack_size"] as short?;
    var CRVId = obj["CRV_Id"] as int?;

    inventoryItems.Add(new WebAPIClientUtils.InventoryItem
    {
        Id = id ?? string.Empty,
        PackSize = packSize.GetValueOrDefault(),
        Description = description ?? string.Empty,
        DeptDotSubdept = deptSubdept.GetValueOrDefault(),
        Unit_Cost = unitCost.GetValueOrDefault(),
        Unit_List = unitList.GetValueOrDefault(),
        UPC_code = UPC_Code ?? string.Empty,
        UPC_pack_size = UPC_packSize.GetValueOrDefault(),
        CRV_Id = CRVId.GetValueOrDefault()
    });
}

decimal用于货币。

于 2013-11-25T19:55:41.270 回答
1

你看到了DBNull.Value,它覆盖ToString()了 return ""

查看

if (obj["Unit_Cost"] == DBNull.Value)

如果obj是 a DataRow,你也可以调用obj.IsNull("Unit_Cost")

于 2013-11-25T19:27:00.090 回答
1

根据此答案以及有关您拥有的类型的最新信息,请尝试执行以下操作:

id = obj.Value<string>("Id") ?? "";
packSize = obj.Value<short?>("PackSize") ?? (short)0;
var description = obj.Value<string>("Description") ?? "";
var deptSubdept = obj.Value<double?>("DeptDotSubdept") ?? 0.0;
var unitCost = obj.Value<double?>("Unit_Cost") ?? 0.0;
...
var crvId = obj.Value<int>("CRV_Id") ?? 0;
于 2013-11-25T21:36:51.577 回答
1

对于默认值,您可以使用 var def = (Double)(obj["Unit_Cost"] ?? default(Double));

于 2013-11-25T19:31:22.077 回答
1

如果你使用DeserializeObject而不是JObject,你可以很容易地用DefaultValueAttributeand做到这一点DefaultValueHandling

void Main()
{
    var item = JsonConvert.DeserializeObject<InventoryItem>(@"{""Id"": 1}",
         new JsonSerializerSettings {
                DefaultValueHandling = DefaultValueHandling.Populate });
    // item.PackSize == 1
}
public class InventoryItem
{
    public string Id { get; set; }
    [DefaultValue(1)]
    public Int16 PackSize { get; set; }
    [DefaultValue("")]
    public string Description { get; set; }
    public Double DeptDotSubdept { get; set; }
}
于 2013-11-25T19:32:56.547 回答
1

尝试这个

Double dbl;
Int16 int16;
Int32 int32;

    foreach (JObject obj in arr)
    {
        id = (string)obj["Id"];
        packSize = Int16.TryParse(obj["PackSize"].ToString(), out int16) ? (Int16)obj["PackSize"]:0;
        var description = (string)obj["Description"];
        var deptSubdept = Double.TryParse(obj["DeptDotSubdept"].ToString(), out dbl) ? (Double)obj["DeptDotSubdept"] : 0.00;
        var unitCost = Double.TryParse(obj["Unit_Cost"].ToString, out dbl) ? (Double)obj["Unit_Cost"] : 0.00;
        var unitList = Double.TryParse(obj["Unit_List"].ToString(), out dbl) ? (Double)obj["Unit_List"] : 0.00;
        var UPC_Code = (string)obj["UPC_code"];
        var UPC_packSize = Int16.TryParse(obj["UPC_pack_size"].ToString(), out int16) ? (Int16)obj["UPC_pack_size"] : 0;
        var CRVId = Int32.TryParse(obj["CRV_Id"].ToString(), out int32) ? (Int32)obj["CRV_Id"] : 0;

    inventoryItems.Add(new WebAPIClientUtils.InventoryItem
    {
        Id = id,
        PackSize = packSize,
        Description = description,
        DeptDotSubdept = deptSubdept,
        Unit_Cost = unitCost,
        Unit_List = unitList,
        UPC_code = UPC_Code,
        UPC_pack_size = UPC_packSize,
        CRV_Id = CRVId
    })
于 2013-11-25T19:34:10.460 回答