所以你必须表Customers和Orders,并且客户和订单之间存在一对多的关系:每个客户都有零个或多个订单,每个订单只属于一个客户,即客户CustomerId 所指的外键。
每个客户都有一个属性时间。 (您确定 Time 是 Customer 的属性,而不是 Order 的属性吗?)。您有两个 DateTime 值:timeStart 和 timeEnd,并且对于在 timeStart 和 timeEnd 之间具有属性时间值的每个客户,您想要他的订单之一,不管是哪一个,如果此客户没有任何订单,则为 null订单。
步步为营:
DateTime timeStart = ... // = '2021-01-01 10:00:00'
DateTime timeEnd = ... // = '2021-01-01 11:00:00'
IQueryable<Order> allOrders = ...
IQueryable<Customer> allCUstomers = ...
IQueryable<Customer> customersWithinTimeRanges = allCustomers
.Where(customer => timeStart <= customer.Time and customer.Time < timeEnd);
换句话说:从所有客户中,只保留属性时间值介于 timeStart 和 timeEnd 之间的客户(使用属性
现在从时间范围内的每个客户那里,您需要他的一个订单,如果客户没有任何订单,则为 null。
只要您有一对多关系,例如学校有零个或更多学生,城市有零个或更多居民,或者在您的情况下:客户有零个或多个订单,并且来自每个“一个”你想要零个或多个他的“许多”项目,考虑使用Queryable.GroupJoin的重载之一
我几乎总是需要带有参数resultSelector的重载
var customersWithAnOrder = customersWithinTimeRanges.GroupJoin(
allOrders,
customer => customer.Id, // from every Customer take the primary key
order => order.CustomerId, // from every Order take the foreign key
// parameter resultSelector: from every Customer with his zero or more Orders
// make one new object:
(customer, ordersOfThisCustomer) => new
{
// select the Customer properties that you plan to use:
Id = customer.Id,
Name = customer.Name,
...
Order = ordersOfThisCustomer.Select(order => new
{
// select the Order properties that you plan to use
Id = order.Id,
Date = order.Date,
...
// not needed, you already got the value in property Id:
// CustomerId = order.CustomerId
})
// you don't need all Orders of this Customer, you only want one,
// don't care which one or null if this Customer doesn't have any Orders
.FirstOrDefault(),
});
如果您没有对序列进行排序,有时数据库不允许您执行FirstOrDefault。在这种情况下,在 FirstOrDefault 之前排序:
Order = ordersOfOfThisCustomer.Select(order => new {...})
.OrderBy(order => order.Date) // or whatever you want to sort on
.FirstOrDefault(),