TickerQ EF Core
Installation
TickerQ.EntityFrameworkCore is a package that extends the functionality of TickerQ.
You can install it with:
cli> dotnet add package TickerQ.EntityFrameworkCore
pmPM> NuGet\Install-Package TickerQ.EntityFrameworkCore
pm<PackageReference Include="TickerQ.EntityFrameworkCore" Version="*" />
Configure Options
Add options in TickerQ.
csharp
using TickerQ.DependencyInjection;
using TickerQ.EntityFrameworkCore.DependencyInjection;
....
services.AddTickerQ(opt =>
{
// Set fallback time out to check for missed jobs and execute.
opt.UpdateMissedJobCheckDelay(timeSpan: ...);
// Set name of instance, default is Environment.MachineName.
opt.SetInstanceIdentifier(identifierName: ...)
....
// Configure the EF Core–backed operational store for TickerQ metadata, locks, and state.
options.AddOperationalStore<MyDbContext>(efOpt =>
{
// Apply custom model configuration only during EF Core migrations
// (design-time). The runtime model remains unaffected.
efOpt.UseModelCustomizerForMigrations();
// On app start, cancel tickers left in Expired or InProgress (terminated) states
// to prevent duplicate re-execution after crashes or abrupt shutdowns.
efOpt.CancelMissedTickersOnAppStart(ReleaseAcquiredTermination.CancelExpired);
// Defined cron-based functions are auto-seeded in the database by default.
// Example: [TickerFunction(..., "*/5 * * * *")]
// Use this to ignore them and keep seeds runtime-only.
ef.IgnoreSeedMemoryCronTickers();
// Seed initial tickers (time-based and cron-based).
ef.UseTickerSeeder(
async timeTicker =>
{
await timeTicker.AddAsync(new TimeTicker
{
Id = Guid.NewGuid(),
Function = "CleanupLogs",
ExecutionTime = DateTime.UtcNow.AddSeconds(5),
});
},
async cronTicker =>
{
await cronTicker.AddAsync(new CronTicker
{
Id = Guid.NewGuid(),
Expression = "0 0 * * *", // every day at 00:00 UTC
Function = "CleanupLogs"
});
});
});
});
❗️If Not Using UseModelCustomizerForMigrations()
You must apply TickerQ configurations manually in your DbContext
:
csharp
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options)
: base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Apply TickerQ entity configurations explicitly
// Default Schema is "ticker".
builder.ApplyConfiguration(new TimeTickerConfigurations(schema: ... ));
builder.ApplyConfiguration(new CronTickerConfigurations(schema: ...));
builder.ApplyConfiguration(new CronTickerOccurrenceConfigurations(schema: ...));
// Alternatively, apply all configurations from assembly:
// builder.ApplyConfigurationsFromAssembly(typeof(TimeTickerConfigurations).Assembly);
}
}
💡 Recommendation:
UseUseModelCustomizerForMigrations()
to cleanly separate infrastructure concerns from your core domain model, especially during design-time operations like migrations.
Note: If you're using third-party libraries (e.g., OpenIddict) that also overrideIModelCustomizer
, you must either merge customizations or fall back to manual configuration insideOnModelCreating()
to avoid conflicts.
Add Migrations
Migrations would be created for Context
that is declared at AddOperationalStore
.
PM
PM> add-migration "TickerQInitialCreate" -c MyDbContext