Reputation: 3737
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?
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
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