Anduin Xue
Anduin Xue

Reputation: 3737

Entity framework - Conditionally query related entities with type converting

I have two class:

public abstract class Conversation
{
    public int Id { get; set; }
}

public class PrivateConversation : Conversation
{
    public ICollection<User> Users { get; set; }
}

In DbContext, there are DbSets:

public DbSet<Conversation> Conversations { get; set; }
public DbSet<PrivateConversation> PrivateConversations { get; set; }
public DbSet<User> Users { get; set; }

Which generates two tables: Conversations and Users.

PrivateConversations are saved in table Conversations

Now an error occurred with query:


// For some reason, I can only query `db.Conversations`, can not access `db.PrivateConversations`
var conversations = db.Conversations
  .Include(t => (t as PrivateConversation).Users)
  .Where(t => t is PrivateConversation)
  .Where(t => (t as PrivateConversation).Users.Any())
  .ToList();

Told me that in Users.Any(), Users is null.

I am very confused. How can I query all private conversations with user in it?

Additional info:

packages I usesd:

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SQLServer" Version="2.2.6" />

runtime: .NET Core 2.2

<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>

Upvotes: 1

Views: 56

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205759

I can't find any documentation regarding this.

According to Include on derived types one can use either as operator or explict cast. And indeed both work for Include. But in standard LINQ operators the as operator is causing client evaluation and the exception in question - client evaluation occurs at a time the navigation properties are not loaded yet (despite the Include). One more reason for removing client evaluation in 3.0.

Back to your issue. The solution is to use explicit cast:

.Where(t => ((PrivateConversation)t).Users.Any())

which correctly translates to SQL, hence has no NRE issues at all.

Upvotes: 2

Related Questions