Click here to Skip to main content
15,887,888 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi. I'm implementing an asp.net core 3.1 project. I have a query which its result is to find average of the differences between two dates that are grouped by year and month like the following query. My problem is, there is an error after running my project for those attributes that I used in my select part of query while they haven't been used in groupby.

The error is:

.FirstOrDefault()' 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 either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information


What I have tried:

C#
var groupedDate =     (from t1 in _context.Apiapp
                                   join t2 in _context.ApiAppHistory on t1.Id         equals t2.ApiAppId
                                   join t3 in _context.EntityType on t2.LastReqStatus equals t3.Id
                                   where t1.IsDeleted == false && t1.LastRequestStatus == t2.Id && t3.Name == "granted"
                                   group new { t1, t2 }
                                   by new { Year = t1.ApiRequestDate.Substring(0, 4), Month = t1.ApiRequestDate.Substring(5, 2), LastReqStatus = t2.LastReqStatus } into g

                                   select new
                                   {
  diff=GetPersianDaysDiffDate(g.FirstOrDefault().t1.ApiRequestDate, g.FirstOrDefault().t2.Date),
                                       Year = g.Key.Year,
                                       Month = g.Key.Month,
                                       GrantedCount = g.Count()

                                   }).ToList();

            var avgDateDiff = groupedDate
                      .GroupBy(x => new { x.Year, x.Month })
                      .Select(x => new { Year = x.Key.Year, Month = x.Key.Month, Avg = x.Average(y => y.diff) })
                      .ToList();


public int GetPersianDaysDiffDate(string Date1, string Date2)
        {
            int year1 = Convert.ToInt16(Date1.Substring(0, 4));
            int month1 = Convert.ToInt16(Date1.Substring(5, 2));
            int day1 = Convert.ToInt16(Date1.Substring(8, 2));

            int year2 = Convert.ToInt16(Date2.Substring(0, 4));
            int month2 = Convert.ToInt16(Date2.Substring(5, 2));
            int day2 = Convert.ToInt16(Date2.Substring(8, 2));

            System.Globalization.PersianCalendar calendar = new System.Globalization.PersianCalendar();
            DateTime dt1 = calendar.ToDateTime(year1, month1, day1, 0, 0, 0, 0);
            DateTime dt2 = calendar.ToDateTime(year2, month2, day2, 0, 0, 0, 0);
            TimeSpan ts = dt2.Subtract(dt1);

            return ts.Days;
        }
        //string Date1 = "1398/01/01";
        //string Date2 = "1398/01/05";

        //int Diff = GetPersianDaysDiffDate(Date1, Date2);
Posted
Updated 22-May-20 3:54am
v4

1 solution

I'm not surprised Entity Framework doesn't know how to convert that to a SQL query! Aside from the fact that the GetPersianDaysDiffDate function probably isn't mapped to a SQL function, it's not clear which dates within the group you want to compare.

For example, if you have five records grouped into January 2020, which single record are you going to take the dates from? You haven't specified an OrderBy on the FirstOrDefault query, so there's no way to know.

Perhaps something like this might work:
C#
var query = from t1 in _context.Apiapp
            join t2 in _context.ApiAppHistory on t1.Id equals t2.ApiAppId
            join t3 in _context.EntityType on t2.LastReqStatus equals t3.Id
            where t1.IsDeleted == false && t1.LastRequestStatus == t2.Id && t3.Name == "granted"
            let tg = new
            {
                Year = t1.ApiRequestDate.Substring(0, 4), 
                Month = t1.ApiRequestDate.Substring(5, 2), 
                t2.LastReqStatus,
                t1.ApiRequestDate,
                t2.Date
            }
            group tg by new { tg.Year, tg.Month, tg.LastReqStatus } into g
            select new
            {
                g.Key.Year,
                g.Key.Month,
                ApiRequestDate = g.Min(i => i.ApiRequestDate),
                Date = g.Max(i => i.Date)
            };

var avgDateDiff = query.AsEnumerable()
    .GroupBy(x => new { x.Year, x.Month }, (key, g) => new
    {
        key.Year,
        key.Month,
        Avg = g.Average(y => GetPersianDaysDiffDate(y.ApiRequestDate, y.Date))
    })
    .ToList();
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900