Linq Issue处理select中的空值

时间:2013-04-24 15:28:07

标签: linq entity-framework linq-to-entities

我的解决方案中有以下实体

public class UtilityAccount : IObjectWithState 
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid UtilityAccountID { get; set; }
    public string Account { get; set; }
    [ForeignKey("Person")]
    public Guid PersonID { get; set; }
    public virtual Person Person { get; set; }
    public string ForeignID { get; set; }
    [NotMapped]
    public ObjectState ObjectState { get; set; }

    public virtual ICollection<Utility> Utilities { get; set; }

    public UtilityAccount()
    {
        Utilities = new List<Utility>();
    }
}

public class Utility : IObjectWithState 
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid UtilityID { get; set; }
    [ForeignKey("UtilityAccount")]
    public Guid UtilityAccountID { get; set; }
    public virtual UtilityAccount UtilityAccount { get; set; }
    public Guid? ServiceAddressID { get; set; }
    [ForeignKey("ServiceAddressID")]
    public virtual Address ServiceAddress { get; set; }
    [NotMapped]
    public ObjectState ObjectState { get; set; }
    public double CurrentBalance { get; set; }
    public double? PendingPaymentTotal { get; set; }
    public string ForeignID { get; set; }
    [ForeignKey("UtilityType")]
    public Guid UtilityTypeID { get; set; }
    public virtual UtilityType UtilityType { get; set; }
    public virtual ICollection<UtilityBill> UtilityBills { get; set; }
    public virtual ICollection<IncomingUtilityPayment> IncomingPayments { get; set; }

    public Utility()
    {
        UtilityBills = new List<UtilityBill>();
        IncomingPayments = new List<IncomingUtilityPayment>();
    }
}

public class IncomingUtilityPayment : IObjectWithState
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid IncomingPaymentID { get; set; }
    public string ForeignID { get; set; }
    [ForeignKey("Utility")]
    public Guid UtilityID { get; set; }
    public virtual Utility Utility { get; set; }
    public DateTime PaymentDate { get; set; } 

    public IncomingPaymentStatus IncomingPaymentStatus { get; set; }
    public double? UtilityAmount { get; set; }
    public double? ConvenienceFee { get; set; }
    public double? TotalAmount { get; set; }

    public string AuthCode { get; set; }
    public string AuthReference { get; set; }
    public string TenderType { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int PaymentIdent { get; set; }

    [NotMapped]
    public ObjectState ObjectState { get; set; }
}

我的问题是我正在尝试使用Linq来检索有关UtilityAccount的信息,并且我遇到了针对实用程序的IncomingPayments的问题。下面是我试图使用的select语句。

returnVal = repo.AllIncluding(o => o.Person, o => o.Utilities, o => o.Utilities.Select(p => p.UtilityType), o => o.Person.BillingAddress, o => o.Utilities.Select(p => p.ServiceAddress), o => o.Utilities.Select(p => p.IncomingPayments.Where(q => q.IncomingPaymentStatus == IncomingPaymentStatus.Pending || q.IncomingPaymentStatus == IncomingPaymentStatus.Processed )));

在我将此条款添加到声明之前,一切都运行良好。

o => o.Utilities.Select(p => p.IncomingPayments.Where(q => q.IncomingPaymentStatus == IncomingPaymentStatus.Pending || q.IncomingPaymentStatus == IncomingPaymentStatus.Processed ))

我认为我的问题最终成为我在Linq条款中写错了。我得到的错误是

The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.

参数名称:路径

我可以使用以下语句,没有问题

o => o.Utilities.Select(p => p.IncomingPayments)

一旦我添加了where子句,我就会收到错误

1 个答案:

答案 0 :(得分:0)

我不熟悉EntityFramework,也不熟悉linq-to-entities,但如果它就像linq-to-object那样你可以:

在使用您的.Where(p => p.IncomingPayments != null)链接之前添加.Select()

o.Utilities.Where(p => p.IncomingPayments != null)
           .Select(p => p.IncomingPayments.Where(q => q.IncomingPaymentStatus == IncomingPaymentStatus.Pending || q.IncomingPaymentStatus == IncomingPaymentStatus.Processed))

结果将是嵌套的IEnumerable,即IEnumerable<IEnumerable<IncomingUtilityPayment>>

如果您确实需要IEnumerable<IncomingUtilityPayment>,那么.SelectMany()可以参加比赛。

o.Utilities.Where(p => p.IncomingPayments != null)
           .SelectMany(p => p.IncomingPayments)
           .Where(q => q.IncomingPaymentStatus == IncomingPaymentStatus.Pending || q.IncomingPaymentStatus == IncomingPaymentStatus.Processed)

希望这个帮助