EF 核心分组不适用于相关模型

发布于 2025-01-16 10:24:48 字数 3632 浏览 1 评论 0原文

我是实体框架的新手。我可以设法创建表和工作 CRUD 操作。

我的模型如下

public class Break
    {
        [JsonProperty("id")]
        public int Id { get; set; }
        [JsonProperty("name")]
        public string Name { get; set; }
        [JsonProperty("duration")]
        public int Duration { get; set; }
        [JsonProperty("countable")]
        public bool Countable { get; set; }
    }

    public class BreakState
    {
        [JsonProperty("id")]
        public int Id { get; set; }
        [JsonProperty("level")]
        public int Level { get; set; }
        [JsonProperty("name")]
        public string Name { get; set; }
        [JsonProperty("isSupervisor")]
        public bool IsSupervisor { get; set; }
        [JsonProperty("isActive")]
        public bool IsActive { get; set; }
    }

    public class BreakRequest : BaseModel
    {
        [JsonProperty("dn")]
        public string DN { get; set; }
        [JsonProperty("agent")]
        public string Agent { get; set; }
        
        [JsonProperty("break")]
        public Break Break { get; set; }

        [JsonProperty("steps")]
        public List<BreakStep> Steps { get; set; }
    }

    public class BreakStep : BaseModel
    {
        [JsonProperty("state")]
        public BreakState BreakState { get; set; }
        [JsonProperty("note")]
        public string Note { get; set; }


        [JsonProperty("request_id")]
        public int BreakRequestId { get; set; }
        [JsonIgnore]
        public BreakRequest BreakRequest { get; set; }
    }

现在我需要从上下文中获取复杂的数据。

public int GetUsedBreak(string agent) {
            int sum_breaks_used = 0;
            var shift = GetShift(agent);
            if (shift != null) {
                using (var dbBreak = new BreakTimeDbContext())
                {
                    var breaks_countable = dbBreak.BreakRequests
                        .Where(x => x.DN == agent && x.Break.Countable && x.Steps.Count == 4 && x.CreatedAt > shift.Start)
                        .Select(x => x.Id).ToArray();
                    if (breaks_countable.Length > 0) {
                        sum_breaks_used = dbBreak.BreakSteps
                            .Include(i => i.BreakState)
                            .Where(w => breaks_countable.Contains(w.BreakRequestId))
                            .GroupBy(x => x.BreakRequestId)
                            .Select(g => new {
                                BreakId = g.Key,
                                Level3Time = g.Where(w => w.BreakState.Level == 3).First().CreatedAt,
                                Level4Time = g.Where(w => w.BreakState.Level == 4).First().CreatedAt
                            })
                            .Sum(x => ( x.Level4Time - x.Level3Time ).Minutes);
                    }
                }
            }
            return sum_breaks_used;
        }

通过这个函数,我尝试获得日期差异的总和。 但我收到以下错误

执行请求时发生未处理的异常。 System.InvalidOperationException:LINQ 表达式 'GroupByShaperExpression: KeySelector:b.BreakRequestId, 元素选择器:EntityShaper表达式: 实体类型:BreakStep 值缓冲区表达式: ProjectionBindingExpression:EmptyProjectionMember 可空:假

 .Where(w => w.BreakState.Level == 3)' 无法翻译。要么以可翻译的形式重写查询,

或者通过插入调用显式切换到客户端评估 “AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”。看 https://go.microsoft.com/fwlink/?linkid=2101038更多信息。

我只需要 4 级和 3 级差异。

我怎样才能用linq实现它?

注:问题标题可能不清楚,可以更改

I'm newbie at entity framework. I can manage to create tables and working CRUD ops.

My models are below

public class Break
    {
        [JsonProperty("id")]
        public int Id { get; set; }
        [JsonProperty("name")]
        public string Name { get; set; }
        [JsonProperty("duration")]
        public int Duration { get; set; }
        [JsonProperty("countable")]
        public bool Countable { get; set; }
    }

    public class BreakState
    {
        [JsonProperty("id")]
        public int Id { get; set; }
        [JsonProperty("level")]
        public int Level { get; set; }
        [JsonProperty("name")]
        public string Name { get; set; }
        [JsonProperty("isSupervisor")]
        public bool IsSupervisor { get; set; }
        [JsonProperty("isActive")]
        public bool IsActive { get; set; }
    }

    public class BreakRequest : BaseModel
    {
        [JsonProperty("dn")]
        public string DN { get; set; }
        [JsonProperty("agent")]
        public string Agent { get; set; }
        
        [JsonProperty("break")]
        public Break Break { get; set; }

        [JsonProperty("steps")]
        public List<BreakStep> Steps { get; set; }
    }

    public class BreakStep : BaseModel
    {
        [JsonProperty("state")]
        public BreakState BreakState { get; set; }
        [JsonProperty("note")]
        public string Note { get; set; }


        [JsonProperty("request_id")]
        public int BreakRequestId { get; set; }
        [JsonIgnore]
        public BreakRequest BreakRequest { get; set; }
    }

Now I need to get complex data from context.

public int GetUsedBreak(string agent) {
            int sum_breaks_used = 0;
            var shift = GetShift(agent);
            if (shift != null) {
                using (var dbBreak = new BreakTimeDbContext())
                {
                    var breaks_countable = dbBreak.BreakRequests
                        .Where(x => x.DN == agent && x.Break.Countable && x.Steps.Count == 4 && x.CreatedAt > shift.Start)
                        .Select(x => x.Id).ToArray();
                    if (breaks_countable.Length > 0) {
                        sum_breaks_used = dbBreak.BreakSteps
                            .Include(i => i.BreakState)
                            .Where(w => breaks_countable.Contains(w.BreakRequestId))
                            .GroupBy(x => x.BreakRequestId)
                            .Select(g => new {
                                BreakId = g.Key,
                                Level3Time = g.Where(w => w.BreakState.Level == 3).First().CreatedAt,
                                Level4Time = g.Where(w => w.BreakState.Level == 4).First().CreatedAt
                            })
                            .Sum(x => ( x.Level4Time - x.Level3Time ).Minutes);
                    }
                }
            }
            return sum_breaks_used;
        }

with this function, I try to get sum of date diffrences.
But I get the error below

An unhandled exception has occurred while executing the request.
System.InvalidOperationException: The LINQ expression 'GroupByShaperExpression:
KeySelector: b.BreakRequestId,
ElementSelector:EntityShaperExpression:
EntityType: BreakStep
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False

      .Where(w => w.BreakState.Level == 3)' could not be translated. Either rewrite the query in a form that can be translated,

or switch to client evaluation explicitly by inserting a call to
'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See
https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

I need only level 4 and level 3 differences.

How can I achieve it with linq?

NOTE: title of the question may not be clear, can change it

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文