Roslyn Source Generators
Use source-generated queries for queries called often enough that parse and mapping overhead matters. Instead of parsing and planning the same SQL pattern repeatedly at runtime, you annotate a static partial method and let the generator emit the call path.
Start with a projection type.
public sealed record PlayerProjection(int Id, string Name, int Level);Then declare a static partial method with [DataVoQuery].
using DataVo.Core;
using DataVo.Core.CompiledQueries;
public static partial class GameQueries
{
[DataVoQuery("SELECT Id, Name, Level FROM Players WHERE Id = @id")]
public static partial PlayerProjection? GetPlayer(DataVoContext db, int id);
}At runtime, call the generated method like ordinary C#.
PlayerProjection? player = GameQueries.GetPlayer(db, 42);The first parameter must be DataVoContext. SQL parameters such as @id must match C# method parameters after the context parameter.
public static partial class PlayerWrites
{
[DataVoQuery("INSERT INTO Players (Id, Name, Level) VALUES (@id, @name, @level)")]
public static partial IReadOnlyList<long> InsertPlayer(DataVoContext db, int id, string name, int level);
[DataVoQuery("UPDATE Players SET Level = @level WHERE Id = @id")]
public static partial int UpdateLevel(DataVoContext db, int id, int level);
}For indexed point lookups, provide a schema manifest as an additional file. The generator can use that manifest to pre-resolve single-column index hints.
<ItemGroup>
<AdditionalFiles Include="datavo.schema.sql" DataVoSchemaManifest="true" />
</ItemGroup>CREATE TABLE Players (
Id INT PRIMARY KEY,
Name VARCHAR(80),
Level INT
);
CREATE INDEX IX_Players_Name ON Players (Name);Use generated queries for stable point reads, inserts, and narrow fixed-shape updates. Use runtime SQL for exploratory queries, joins, aggregates, vector search, and complex SQL.
Source Generator Support Summary
The generator supports static partial methods whose first parameter is a DataVoContext, with SQL/C# parameter validation, and it emits compiled paths for equality SELECT, INSERT INTO ... VALUES (...), and UPDATE ... SET ... WHERE ..., plus typed projection mappers and single-column schema-manifest index hints. It does not generate DELETE, joins, aggregates, or vector search, and it is not a full LINQ provider — use runtime SQL for those shapes.