相关字段为空的 Linq 查询

Linq Query with Null for Related Field

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

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

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 字段标记为可为空,但由于它是一个虚拟字段, 它没有用,我得到一个错误 "The type Vehicle must be a non-nullable value...."

这是我的模型的样子(缩写):

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 表单中使用 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();

这会产生不同的错误:{"The specified argument value for the function is not valid. [ Argument # = 2,Name of function(if known) = case ]"}

如果 t.Vehicle 为 null,则使用 t.Vehicle.VehicleNumber 将产生错误。

尝试:

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

这会测试正确的项目是否为 null。

您还可以添加构建器 class 一个初始化,特别是如果它是一个列表...

public class Transaction
{


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

}

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

    public Vehicle Vehicle { get; set; }

    ...
}