In MS SQL Server I have a table that contains a history of calls to contacts (that is another table). Accessed by EF, The Entities are the following:
public partial class CallbackHistory
{
public int HistoryId { get; set; }
public int CompanyId { get; set; }
public int CallerId { get; set; }
public DateTime LastCallTimeStamp { get; set; }
public virtual CompanyDiary Caller { get; set; }
public virtual Company Company { get; set; }
}
and
public partial class CompanyDiary
{
public CompanyDiary()
{
DatiCallbackHistory = new HashSet<DatiCallbackHistory>();
}
public int CallerId { get; set; }
public string NickName { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public int CompanyId { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<CallbackHistory> CallbackHistory { get; set; }
}
I need to get a list of the last 5 calls to individual numbers order by date descending.
I came up with the following query that could not be translated to SQL, unfortunately:
var historyOfCalls = await
context.CallbackHistoryDbSet
.Include(historyEntry => historyEntry.Caller)
.Where(historyEntry => historyEntry.CompanyId == companyId)
.GroupBy(s => s.Caller.PhoneNumber)
.Select(s => s.OrderByDescending(historyEntry => historyEntry.LastCallTimeStamp).FirstOrDefault())
.Take(5)
.AsNoTracking()
.ToListAsync(cancellationToken).ConfigureAwait(false);
Here is the error I get:
System.AggregateException
HResult=0x80131500
Message=One or more errors occurred. (The LINQ expression '(GroupByShaperExpression:
KeySelector: (c.PhoneNumber),
ElementSelector:(EntityShaperExpression:
EntityType: CallbackHistory
ValueBufferExpression:
(ProjectionBindingExpression: EmptyProjectionMember)
IsNullable: False
)
)
.OrderByDescending(historyEntry => historyEntry.LastCallTimeStamp)' 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.)
Source=System.Private.CoreLib
Inner Exception 1:
InvalidOperationException: The LINQ expression '(GroupByShaperExpression:
KeySelector: (c.PhoneNumber),
ElementSelector:(EntityShaperExpression:
EntityType: CallbackHistory
ValueBufferExpression:
(ProjectionBindingExpression: EmptyProjectionMember)
IsNullable: False
)
)
.OrderByDescending(historyEntry => historyEntry.LastCallTimeStamp)' 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.
It seems that the problem lies in the fact that I'm grouping on a navigation property.
Can I rewrite this query to make it translatable to SQL?
I have no clue when to switch to Linq to objects with this query As I already have a call to ToListAsync
. I've tried to move it after Select
in the query but it does not compile