ProfileQuery#

Describes what a load profile covers: a date range, the resources, the bucket size and which buckets list their tasks. Create one with new ProfileQuery(from, to) and pass it to Project.LoadProfile or set it as PreviewOptions.Profile.

Declaration#

namespace Plen;

public sealed class ProfileQuery : IDeepCloneable<ProfileQuery>
{
    public ProfileQuery(Moment from, Moment to);

    public Moment From { get; set; }
    public Moment To { get; set; }
    public List<Id>? Resources { get; set; }
    public Basis? Basis { get; set; }
    public ProfileTasks Tasks { get; set; } = ProfileTasks.None;

    public ProfileQuery DeepClone();
}

ProfileQuery converts implicitly to LoadProfileOptions, so project.LoadProfile(query) compiles without wrapping the query. It doesn't implement IEquatable<T>, so two instances compare by reference.

Constructors#

ProfileQuery(Moment, Moment)#

public ProfileQuery(Moment from, Moment to)

Creates a query over [from, to) for every resource, on the derived basis, with no task lists.

Name Type Description
from Moment Start of the range (inclusive).
to Moment End of the range (exclusive).

The constructor doesn't validate the range. The call that reads the query checks it.

Properties#

Property Type Default Description
From Moment constructor argument Start of the range. The profile holds every bucket whose start lies in [From, To).
To Moment constructor argument End of the range (exclusive).
Resources List<Id>? null Resources to profile, in this order. null profiles every resource.
Basis Basis? null Bucket size. null derives it from SchedulingConfig.DurationUnit.
Tasks ProfileTasks ProfileTasks.None Which buckets list their booked tasks in LoadBucket.Tasks.

Validation#

Project.LoadProfile and Project.Preview throw an InputException for an invalid query:

Path When
to To <= From, or the range holds more than 100 000 buckets per resource
resources Resources names a resource that isn't in the project

Methods#

DeepClone#

public ProfileQuery DeepClone()

Returns a copy that shares no list with this one.

Example#

using Plen;

var monday = Moment.FromYmdHm(2026, 1, 5, 0, 0) ?? throw new InvalidOperationException("invalid date");
var nextMonday = Moment.FromYmdHm(2026, 1, 12, 0, 0) ?? throw new InvalidOperationException("invalid date");

var data = new ProjectData
{
    Tasks =
    [
        new TaskData("design") { StartDate = monday, Duration = 3.0 },
        new TaskData("review") { StartDate = monday, Duration = 2.0 },
    ],
    Resources = [new ResourceData { Id = "dev1" }],
    Assignments =
    [
        new AssignmentData { Task = "design", Resource = "dev1", Value = 1.0 },
        new AssignmentData { Task = "review", Resource = "dev1", Value = 0.5 },
    ],
};

var project = new Project();
project.Solve(data, new SolveOptions());

var query = new ProfileQuery(monday, nextMonday)
{
    Resources = ["dev1"],
    Basis = Basis.Day,
    Tasks = ProfileTasks.Over,
};

var profile = project.LoadProfile(query);

foreach (var bucket in profile.Resources[0].Buckets)
    Console.WriteLine($"{bucket.Start}: {bucket.Load} / {bucket.Capacity}");