一对多并在多个中搜索 (IQueryable) (linq)

One to many and search in many (IQueryable) (linq)

我的数据库中有这种关系:

Order => historyStatus => Status

Order 包含 HistoryStatus 的列表,HistoryStatus 包含一个 Status.

我的用例是:使用确定的 Status 搜索所有 Order 并获取最新的 HistoryStatus(基于日期)

如何在 linq to entities 和 IQueryable 中做到这一点?

以下是实体:

public class Order 
{
   public int ID { get; set; }

   public virtual ICollection<HistoryStatusOrder> HistoriesStatusOrder { get; set; }
}

public class HistoryStatusOrder 
{
    public int ID { get; set; }
    public DateTime Date { get; set; }
    public string StatusOrderCode { get; 
    public int  OrderId { get; set; }

    public virtual StatusOrder StatusOrder { get; set; }
    public virtual Order Order { get; set; }
}

public class StatusOrder : IEntityBase<string>
{
    public string ID { get; set; }

    public virtual ICollection<HistoryStatusOrder> HistoriesStatusOrder { get; set; }
}

这是我的 Search 方法:

// do multiple searches
if (searchOrderVM.OrderNumber != null)
    queryable = queryable.Where(x => x.OrderNumber.ToString().Contains(searchOrderVM.OrderNumber.ToString()));

// Next 
if (searchOrderVM.SelectedOrdersStatus != null)
{
    // Need to return queryable = ....
}

// Next search...
....

// Finally I do .ToList() to launch the query in database.

感谢您的帮助:)

这会找到所有 Orders,其中 Order 的最新 HistoryStatusOrder 具有特定的 StatusOrderCode:

var results = orders.Where (o => o.HistoriesStatusOrder
    .OrderByDescending (hso => hso.Date)
    .First().StatusOrderCode == "foobar");

(假设每个Order总是至少有一个HistoryStatusOrder

您可以用不同的方式编写此查询以保留 IQueryable<Order>:

var results = orders
    .Select (o => new {
        Order = o,
        LatestHistoryStatusOrder = o.HistoriesStatusOrder
            .OrderByDescending (hso => hso.Date)
            .First()
    })
    .Where (x => x.LatestHistoryStatusOrder.StatusOrderCode == "foobar")
    .Select (x => x.Order);

foreach(var order in results)
{
    // Here you can access:
    //  order.ID
}

如果您想继续访问 LatestHistoryStatusOrder,您可以跳过最后一个 .Select(x => x.Order) 语句:

var results = orders
    .Select (o => new {
        Order = o,
        LatestHistoryStatusOrder = o.HistoriesStatusOrder
            .OrderByDescending (hso => hso.Date)
            .First()
    })
    .Where (x => x.LatestHistoryStatusOrder.StatusOrderCode == "foobar");

foreach(var item in results)
{
    // Here you can access:
    //   item.Order.ID
    //   item.LatestHistoryStatusOrder
}