【问题标题】:LINQ Get full list of objects, include only the properties that match certain conditionLINQ 获取对象的完整列表,仅包含符合特定条件的属性
【发布时间】:2020-05-30 22:47:41
【问题描述】:

我有这两个模型:

    public class Seat
    {
        public int Id { get; set; }
        public ICollection<Reservation> Reservations { get; set; }
    //..
    }

    public class Reservation
    {
        public int Id { get; set; }
        public int SeatId { get; set; }
        public Seat Seat { get; set; }
        public DateTime DateTime { get; set; }
        //..
    }

假设一个座位在一周中的每一天都有预订。我想进行查询,以获取座位并过滤请求日期的座位预订。我想显示座位并显示 X 天免费/保留的座位。 我尝试实现它的方式:

        var seats = _dbContext.Seats
             .Include(s => s.Reservations.Where(r => r.DateTime.Date == dateParam.Date));
        // InvalidOperationException: 'Lambda expression used 
        // inside Include is not valid.'

样本

       var seats = _dbContext.Seats
             .Include(s => s.Reservations)
             .Where(r => r.Reservations.Any(r => r.DateTime.Date == dateParam.Date));   
        // Gets the seats which meet the condition. I want these, but also I want the free seats

样本

        var seatsFiltered = _dbContext.Seats
             .Include(t => t.Reservations)
             .Where(r => r.Reservations.Any(r => r.DateTime.Date == dateParam.Date))
             .ToList();

        var seats = _dbContext.Seats
             .ToList()
             .Select(x => { x.Reservations = new List<Reservation>(); return x; })
             .Concat(seatsFiltered);
        // Not optimal since I obviously ToList twice
        // In the end I get an empty list

        return (ICollection<Seat>)seats;

编辑:按要求添加示例数据:

座位

Id|AreaId|
--|------|
 1|3     | 
 2|3     |
 3|3     |
 4|3     |
 5|3     |
 6|3     |
 7|3     |
 8|3     |

预订

Id|SeatId|Name|Phone|DateTime           |
--|------|----|-----|-------------------|
 7|     1|    |     |2020-02-15 20:30:00|
 8|     1|    |     |2020-02-21 12:00:00|
 9|     1|    |     |2020-02-23 09:00:00|
10|     2|    |     |2020-02-15 20:30:00|
11|     2|    |     |2020-02-21 12:00:00|
12|     2|    |     |2020-02-23 09:00:00|
13|     4|    |     |2020-02-21 12:00:00|
15|     7|    |     |2020-02-15 20:30:00|
16|     7|    |     |2020-02-21 12:00:00|
17|     8|    |     |2020-02-21 12:00:00|
14|     8|    |     |2020-02-23 09:00:00|
18|     3|    |     |2020-02-15 20:30:00|
19|     3|    |     |2020-02-21 12:00:00|
20|     3|    |     |2020-02-23 09:00:00|

当我尝试 Phong 的代码时,出现以下错误:

System.InvalidOperationException: 'LINQ 表达式'(GroupByShaperExpression: KeySelector: (r.SeatId), 元素选择器:(实体形状表达式: 实体类型:预订 值缓冲区表达式: (ProjectionBindingExpression:EmptyProjectionMember) IsNullable: 假 ) ) .ToList()' 无法翻译。以可翻译的形式重写查询,或通过插入对 AsEnumerable()、AsAsyncEnumerable()、ToList() 或 ToListAsync() 的调用显式切换到客户端评估。请参阅https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。'

【问题讨论】:

  • 能否请您提供您的样本数据以及相应的结果?
  • 此外,Reservation 不应包含 Seat 对象。它已经包含SeatId 以便能够参考。
  • 好的Seat 可能是多余的,我刚刚遵循了有关建立关系的指南。 2020-02-15 的结果将返回所有座位,包括 DateTime 值为 2020-02-15 20:30:00 的预订,因为这是我用作示例的座位。

标签: .net entity-framework linq .net-core entity-framework-core


【解决方案1】:

你应该像下面这样GroupBy()

var seatsFiltered = _dbContext.Reservations
                          .Where(r => r.DateTime.Date == dateParam.Date))
                          .GroupBy(r => r.SeatId)
                          .Select(g => new 
{
  SeatId = g.Key,
  ListOfReservations = g // No need to .ToList() here
}) .ToList();

【讨论】:

  • 感谢您的意见。当我尝试你的代码时,我得到一个未处理的异常。我想我需要一些时间来理解代码和异常。同时,我会将异常消息粘贴到我的问题中(评论太长)。
  • 您使用的是哪种实体框架? EF 6 还是 EF 核心?
  • 无论如何,请把ListOfReservations = g.ToList()中的.TolList删除到ListOfReservations = g
  • 我刚刚更新了我的答案,请看@Dragomir
【解决方案2】:

Phong 的解决方案可能绝对有效且有用,但由于我自己无法理解并应用它,所以我使用了这种方法

var seats = _dbContext.Seats.ToList();
var reservations = _dbContext.Reservations.Where(r => r.DateTime.Day == dateTime.Day).ToList();

foreach (var seat in seats)
{
    seat.Reservations = reservations.Where(r => r.SeatId == seat.Id).ToList();
}

我仍然相信还有一个 LINQ one-liner 可以做到这一点,而不会对每个集合造成 .ToList()-ing 的性能影响,但我想不通 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-19
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 2020-04-04
    • 2018-12-02
    • 1970-01-01
    相关资源
    最近更新 更多