1 year ago

#327190

test-img

ZetaD

EF core grouping not working with related model

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

c#

entity-framework-core

ef-core-5.0

0 Answers

Your Answer

Accepted video resources