【问题标题】:One to many and search in many (IQueryable) (linq)一对多和多搜索 (IQueryable) (linq)
【发布时间】:2017-04-13 09:02:42
【问题描述】:

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

Order => historyStatus => Status

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

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

如何在 linq to entity 和 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.

感谢您的帮助:)

【问题讨论】:

  • 您的意思是“查找每个订单的最新 [具有特定状态值的历史状态]”还是“查找每个订单的历史状态,其中 最新 历史状态具有特定状态值”?另外,您提到的日期是哪个属性?
  • 我需要检索一个 IQueryable 所以我需要根据 Date 和 StatusOrderCode 找到所有具有最新 HistoryStatusOrder 的订单。我添加了缺少的道具。

标签: c# entity-framework linq iqueryable


【解决方案1】:

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

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

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

您可以用不同的方式编写此查询来保留IQueryable&lt;Order&gt;

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 =&gt; 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
}

【讨论】:

  • 感谢您的回答,但这不是我想要的。我需要返回一个 IQueryable 因为我进行了多次搜索。我将在我的第一个问题中解释这一点:)。
  • @Goba 我添加了一个应该保留IQueryable&lt;Order&gt;的示例
  • 谢谢,它可能有效,但我使用 ORACLE 11g,我现在有这种错误:/“oracle 11.2.0.3.0 不支持应用”
  • @Goba 嗯,这似乎是 known problem for EntityFramework,并且可能会在针对 Oracle 数据库的许多不同查询中发生。
  • @Goba 我建议您查看适用于 .NET 的 Oracle 数据提供程序的较新版本;也许这会有所帮助,或者升级到显然支持APPLY 的 Oracle 12。恐怕我没有使用 Oracle DB 的经验,所以我无法为您提供更多帮助。
猜你喜欢
  • 1970-01-01
  • 2020-06-21
  • 2021-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-21
  • 2019-05-10
  • 1970-01-01
相关资源
最近更新 更多