【问题标题】:Linq: dynamic Where clause inside a nested subquery get latest records of each groupLinq:嵌套子查询中的动态Where子句获取每个组的最新记录
【发布时间】:2025-12-09 23:15:02
【问题描述】:

我目前在下面遇到动态 linq 表达式的问题

我的模特

public class Orders
{
    public int OrderId ;
    public ICollection<OrderStatuses> Statuses;
}  

public class Statuses
{
    public int StatusId;
    public int OrderId;
    public string Note;
    public DateTime Created;
}

我的样本数据:

Orders
|  ID   | Name       |
----------------------
|   1   | Order 01   |  
|   2   | Order 02   | 
|   3   | Order 03   | 

Statuses
|ID | OrderId | Note      | Created   |
---------------------------------------
| 1 |  1      | Ordered   | 2016-03-01|
| 2 |  1      | Pending   | 2016-04-02|
| 3 |  1      | Completed | 2016-05-19|
| 4 |  1      | Ordered   | 2015-05-19|
| 5 |  2      | Ordered   | 2016-05-20|
| 6 |  2      | Completed | 2016-05-19|
| 7 |  3      | Completed | 2016-05-19|

我想获得票据价值等于 'Ordered'ma​​x created time 的订单数量。 以下是我期望从查询中获得的示例订单数

| Name     |  Note    |  Last Created|
-------------------------------------|
| Order 01 |  Ordered | 2016-03-01   | 
| Order 02 |  Ordered | 2016-05-20   |

这是我的想法,但它似乎是错误的方式

var outer = PredicateBuilder.True<Order>();

var orders   = _entities.Orders
                        .GroupBy(x => x.OrderId)
                        .Select(x => new { x.Key, Created = x.Max(g => g.Created) })
                        .ToArray();

var predicateStatuses = PredicateBuilder.False<Status>();

foreach (var item in orders)
{
    predicateStatuses = predicateStatuses.Or(x => x.OrderId == item.Key && x.Created == item.Created);
}
var predicateOrders = PredicateBuilder.False<JobOrder>();

predicateOrders = predicateOrders.Or(predicateStatuses); (I don't how to passed expression which different object type (Order and Status) here or I have to write an extension method or something

outer = outer.And(predicateOrders);

请建议我在这种情况下如何解决这个动态 linq 表达式。 提前致谢。

【问题讨论】:

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


    【解决方案1】:

    您的查询没有什么动态的,至少不需要这样。您可以将其表示为常规查询。

    var query =
        from o in db.Orders
        join s in db.Statuses on o.Id equals s.OrderId
        where s.Note == "Ordered"
        orderby s.Created descending
        group new { o.Name, s.Note, LastCreated = s.Created } by o.Id into g
        select g.First();
    

    ps,您的模型似乎与数据完全不匹配,所以我忽略了这一点。根据需要进行调整。

    【讨论】:

    • 非常感谢您的回答。实际上,我忘记了 name 属性,我刚刚创建了示例模型来演示我的问题。在我的代码中,我已经实现了动态 Linq,所以我仍在寻找动态 Linq 的解决方案
    【解决方案2】:

    非常感谢@Jeff Mercado 的回答。最后,我定制了你的答案来解决我的问题:

    var predicateStatuses = PredicateBuilder.False<Order>();
    predicateStatuses = predicateStatuses.Or(p => (
                                            from j in db.Statuses 
                                            where j.OrderId == p.ID
                                            group j by j.OrderId into g
                                            select g.OrderByDescending(t=>t.Created)
                                            .FirstOrDefault()
                                        ).FirstOrDefault().Note == 'Ordered'
                                    );
    

    【讨论】:

      最近更新 更多