Linq查询与Null相关的字段

时间:2015-12-30 14:19:45

标签: c# linq nullreferenceexception nullable

我在使用EF 6和Linq保存和检索相关记录方面遇到了一些问题。

我有两个相关的实体,车辆和交易。当进入交易时,用户在保存交易之前从组合框中选择车辆。车辆不是交易中的必填字段,有时交易没有相关车辆。目前,我在尝试将车辆添加到交易之前,使用以下代码检查组合框是否为空。

if ( !string.IsNullOrEmpty( row.Cells[3].FormattedValue as String ) )
{
    // A truck has been selected
    int iSelectedVehicle;
    if ( int.TryParse( row.Cells[3].Value.ToString(), out iSelectedVehicle ) )
    {
        oTransaction.Vehicle = db.Vehicles.First( v => v.ID == iSelectedVehicle );
    }

}

这似乎工作正常,直到我尝试使用Linq查询检索事务。当查询执行时,我得到

"Object reference not set to an instance of an object."

因为Vehicle字段为null。我该如何处理这种情况?我尝试将Transaction中的Vehicle字段标记为可为空,但由于它是一个虚拟字段, 它没有工作,我得到一个错误"类型车辆必须是一个不可空的价值...."

这就是我的模型(缩写):

public class Transaction
{
    [Key]
    public int ID { get; set; }

    ...

    public virtual Vehicle Vehicle { get; set; }

    ...
}

public class Vehicle
{
    [Key]
    public int ID { get; set; }

    [Required]
    [Index]
    public int VehicleNumber { get; set; }

    ...
}

这是我的疑问:

var transactions = ( from t in db.Transactions.AsEnumerable()
                     select new
                     {
                         Product = t.Product.ProductCode,
                         Description = t.Product.Description,
                         Transaction_Type = t.TransactionType.AddRemove,
                         Quantity = t.TransactionType.AddRemove == "Addition"
                                 ? t.FullQuantity + ( t.PartialQuantity / t.Product.Pieces )
                                 : -1 * ( t.FullQuantity + ( t.PartialQuantity / t.Product.Pieces ) ),
                         //Truck = t.Vehicle.VehicleNumber.ToString() ?? string.Empty, // This is the error line. I was trying to check for null but...
                         POJob = t.SourceNumber,
                         Transaction_Date = t.TransactionDate,
                         RecordedBy = t.User.Name,
                         RecordedDate = t.CreateDate
                     } ).ToList();

这似乎是一种相当普遍的情况,但我似乎无法解决这个问题。

我在Windows Forms中使用Code First。

更新

根据Philip Smith的回答修改了查询:

var transactions = ( from t in db.Transactions.DefaultIfEmpty()
                                     select new
                                     {
                                         Product = t.Product.ProductCode,
                                         Description = t.Product.Description,
                                         Transaction_Type = t.TransactionType.AddRemove,
                                         Quantity = t.TransactionType.AddRemove == "Addition"
                                                 ? t.FullQuantity + ( t.PartialQuantity / t.Product.Pieces )
                                                 : -1 * ( t.FullQuantity + ( t.PartialQuantity / t.Product.Pieces ) ),
                                         Truck = t.Vehicle == null ? string.Empty : t.Vehicle.VehicleNumber.ToString(),
                                         POJob = t.SourceNumber,
                                         Transaction_Date = t.TransactionDate,
                                         CreatedBy = t.CreatedBy.Name,
                                         CreatedDate = t.CreateDate,
                                         LastUpdatedBy = t.LastUpdatedBy.Name,
                                         LastUpdated = t.LastUpdatedDate,
                                     } ).ToList();

这会产生不同的错误:{"该函数的指定参数值无效。 [参数#= 2,函数名称(如果已知)= case]"}

2 个答案:

答案 0 :(得分:2)

如果t.Vehicle.VehicleNumber为空,则使用t.Vehicle会生成错误。

尝试:

 t.Vehicle == null ? string.Empty : t.Vehicle.VehicleNumber.ToString();

这会测试null的正确项目。

答案 1 :(得分:0)

您还可以将构建器类添加为初始化,尤其是如果它是列表...

public class Transaction
{


public Transaction()
{
 this.Vehicle = new Vehicle ();

}

[Key]
    public int ID { get; set; }
    ...

    public Vehicle Vehicle { get; set; }

    ...
}