Entity Framework Core - This may indicate either a bug or a limitation in EF Core

asp.net entity-framework-core linq

Question

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 Database strcuture 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

1
2
3/1/2020 1:06:59 PM

Popular Answer

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)
2
3/1/2020 5:50:36 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow