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