I want to load from a user the newest private chat messages.
My code to load the newest messages
public async Task<List<UserChatMessage>> GetUserPrivateChatMessagesAsync(string userId, string userChatPartnerId, int limit, int skip, CancellationToken cancellationToken) {
cancellationToken.ThrowIfCancellationRequested();
if (userId == null) throw new ArgumentNullException(nameof(userId));
if (userChatPartnerId == null) throw new ArgumentNullException(nameof(userChatPartnerId));
return await this.Context.Messages
.OrderBy(d => d.CreatedDate)
.AsNoTracking()
.Include(p => p.UserChatPartner)
.Where(u => u.UserId == userId && u.UserChatPartnerId == userChatPartnerId || u.UserChatPartnerId == userId && u.UserId == userChatPartnerId)
.TakeLast(limit)
.Skip(skip)
.ToListAsync(cancellationToken);
}
The following code throw this error:
System.InvalidOperationException: Processing of the LINQ expression 'DbSet<UserChatMessage>
.OrderBy(d => d.CreatedDate)
.Include(p => p.UserChatPartner)
.Where(u => u.UserId == __userId_0 && u.UserChatPartnerId == __userChatPartnerId_1 || u.UserChatPartnerId == __userId_0 && u.UserId == __userChatPartnerId_1)
.TakeLast(__p_2)' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.
I changed .Take to .TakeLast and now I get the described error.
Database structure of UserChatMessage
I also tried to change ToListAsync to AsEnumerable without success.
I hope somebody understand the error and can help me.
Thanks in advance.
Regard Timo
The error means you are hitting current EF Core bug or limitation.
I changed
.Take
to.TakeLast
and now I get the described error.
So you know what caused the issue. In general avoid LINQ methods having Last
in name (like Last
, LastOrDefault
, TakeLast
) - these have no direct equivalent in SQL world, hence have bigger chance to hit bugs/limitations (or just not supported) by query translators.
Instead, invert the ordering and use the corresponding First
method.
Applying it to your case means replacing
.OrderBy(d => d.CreatedDate)
with
.OrderByDescending(d => d.CreatedDate)
and
.TakeLast(limit)
with
.Take(limit)