C# 相关字段为空的Linq查询

C# 相关字段为空的Linq查询,c#,linq,nullreferenceexception,nullable,C#,Linq,Nullreferenceexception,Nullable,使用EF 6和Linq保存和检索相关记录时遇到一些问题 我有两个相关实体,车辆和交易。输入交易时,用户在保存交易前从组合框中选择车辆。车辆不是交易的必填字段,有时交易没有相关车辆。目前,我正在使用下面的代码检查组合框是否为空,然后再尝试将车辆添加到事务中 if ( !string.IsNullOrEmpty( row.Cells[3].FormattedValue as String ) ) { // A truck has been selected int iSelected

使用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,但由于它是一个虚拟字段, 它不起作用,我得到一个错误“车辆类型必须是不可为空的值…”

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

我的问题是:

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窗体中首先使用代码

更新

根据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,函数名称(如果已知)=大小写]”}

如果
t.Vehicle.vehiclerNumber
为空,则使用
t.Vehicle
将生成错误

尝试:


这将测试正确的项目是否为空。

您还可以添加生成器类a initialize,特别是如果它是一个列表

public class Transaction
{


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

}

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

    public Vehicle Vehicle { get; set; }

    ...
}

因此,如果
Transaction
对象上的
Vehicle
属性为空,是否要跳过该记录?您可能会得到
类型Vehicle必须是不可为空的值
,因为您已将其设置为
必需的
。我仍希望检索记录,但Vehicle字段为空。我有必需的VehicleNumber,但这在车辆模型中,而不是在事务模型中。感谢@philip,当我用上面的一行替换查询中的行时,我得到{“函数指定的参数值无效。[参数#=2,函数名称(如果已知)=case]”},我从车辆模型中取出了“必需的”,我根据你的回答修改了上面的问题。我想我明白了!当我正在努力解决这个问题时,我将
从db.Transactions.AsEnumerable()中的t更改为
从db.Transactions.DefaultIfEmpty()中的t更改为
,当我将其更改回AsEnumerable()时,使用您提供的行,一切似乎都正常。谢谢你的帮助!
 t.Vehicle == null ? string.Empty : t.Vehicle.VehicleNumber.ToString();
public class Transaction
{


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

}

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

    public Vehicle Vehicle { get; set; }

    ...
}