Home > database >  EF Core First Eager Loading Inheritance Filter
EF Core First Eager Loading Inheritance Filter

Time:02-18

I have the following entities defined:

public class Computer
{
    [Key]
    public int Id { get; set; }

    [Required]
    [StringLength(15)]
    public string Name { get; set; } = null!;

    [Required]
    public List<ComputerAction> Actions { get; set; } = new();
}

public abstract class ComputerAction
{
    [Key]
    public int Id { get; set; }

    public List<HistoryEntry> History { get; set; } = new();

    public Computer Computer { get; set; } = null!;

    [NotMapped]
    public Status Status => History.LastOrDefault()?.Status ?? Status.Unknown;

    public abstract Task<HistoryEntry> ExecuteAsync();
}

public class RenewCertificateAction : ComputerAction
{
    public override Task<HistoryEntry> ExecuteAsync() 
    {
        // Whatever
    }
}

public class PingAction : ComputerAction
{
    private readonly Ping _ping = new();

    public override async Task<HistoryEntry> ExecuteAsync()
    {
        // Whatever
    }
}

public class HistoryEntry
{
    [Key]
    public int Id { get; set; }

    [Required]
    public Status Status { get; set; }

    [Required]
    public DateTime WhenExecuted { get; set; }
}

And my DbContext as follows:

public class ComputerContext : DbContext
{
    public ComputerContext(DbContextOptions<ComputerContext> options)
        : base(options)
    {
    }

    public static readonly string ComputerDb = nameof(ComputerDb);

    public DbSet<Computer> Computers { get; set; } = null!;

    public DbSet<RenewCertificateAction> RenewCertificateActions { get; set; } = null!;

    public DbSet<PingAction> PingActions { get; set; } = null!;

    public DbSet<HistoryEntry> History { get; set; } = null!;

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Computer>().HasMany(x => x.Actions).WithOne(x => x.Computer).OnDelete(DeleteBehavior.Cascade);
        modelBuilder.Entity<ComputerAction>().ToTable("ComputerActions").HasMany(x => x.History).WithOne().OnDelete(DeleteBehavior.Cascade);
        modelBuilder.Entity<HistoryEntry>().ToTable("ComputerActionEntries");
    }
}

I'd like to get a list of all computers, but if they happen to have an action of type PingAction, then also load that action (and only that action, not all actions).

What is logical to me is something like dbContext.Computers.Include(x => x.Actions.OfType<PingAction>()) but that apparently can't be translated into a query. How can I do an Include only of Actions of a particular type?

CodePudding user response:

you can use where inside include:

dbContext.Computers.Include(x => x.Actions.Where(action => action is PingAction))

more explanation: : https://stackoverflow.com/a/61147681/11143288

  • Related