如何在 EF4 中按筛选的 Max 查询进行查询和排序
本文关键字:查询 Max 排序 筛选 EF4 | 更新日期: 2023-09-27 18:31:36
>上下文: EF4, C#, .NET4, SQL2008/R2
要重现问题的表/实体:
-
Account (long Id, string Name, etc.)
-
Order (long Id, DateTime DateToExecute, int OrderStatus, etc.)
-
AccountOrder (long Id, long AccountId, long OrderId)
<-是的,一个帐户可能有多个订单,同样,一个订单可能与多个帐户相关联。 -
OrderedItem (long Id, long OrderId, long ItemId, etc)
<-一个订单可能有很多项目,我们希望急切加载这些项目(我意识到这会影响性能/数据大小)。
伪代码(近乎真实的代码)非常适合工作:
DateTime startDateInclusive = xxxx;
DateTime stopDateExclusive = yyy;
var query = Db.Accounts.Include(a => a.AccountOrders.Select(ao => ao.Order.Ordereditems.Select(oi => oi.Item)))
.Where(account =>
account.AccountOrders.Where(ao => ao.OrderStatus != 42)
.Max(ao => ao.DateToExecute).IsBetween(startDateInclusive, stopDateExclusive))
.OrderBy(account =>
account.AccountOrders.Where(ao => ao.OrderStatus != 42)
.Max(ao => ao.DateToExecute));
var results = query.Take(5).ToList();
在英语中,这是在寻找接下来的 5 个帐户,这些帐户的最后一个订单将在某个日期范围内执行。但是,也有一些订单可以取消,因此我们必须在执行该最大值时排除订单状态 42。
问题围绕此筛选的多对多表中的最大日期展开。增加的复杂性是我们需要按过滤后的最大值进行排序,并且我们必须在不破坏我们急切加载的情况下完成上述所有操作(即连接必须通过 Where 中的投影完成,而不是使用 .加入)。我不确定如何在结果比应有的复杂 10 倍的情况下进行此查询。我不想做连接来过滤 ao。OrderStatus/Max the DateToExecute 3次(一次用于开始日期,一次用于停止日期,一次用于排序)。显然,IsT之間不起作用。
关于如何以这种方式对生成的 SQL 以相当有效的方式执行此查询的任何想法?
在此处使用匿名类型可能会有所帮助:
DateTime startDateInclusive = xxxx;
DateTime stopDateExclusive = yyy;
var query = Db.Accounts
.Select(account => new {
Account = account,
MaxDate = account.AccountOrders.Select(ao => ao.Order).Where(o => o.OrderStatus != 42).Max(o => o.DateToExecute)
})
.Where(a => a.MaxDate >= startDateInclusive && a.MaxDate < stopDateExclusive)
.OrderBy(a => a.MaxDate)
.Select(a => a.Account)
.Include(a => a.AccountOrders.Select(ao => ao.Order.Ordereditems.Select(oi => oi.Item)));
var results = query.Take(5).ToList();
这是未经测试的,因为我没有任何数据源可以测试。 但这可能是您需要做的最简单的方法。