Advanced customization
Type mapping
public readonly record struct PositionalValue<T>(T Value);
TypeParsingInfo.AddOrSet(typeof(PositionalValue<>), CtorTypeInfo.Instance);
static readonly QueryCommand CountAlbums = new("SELECT COUNT(*) FROM albums");
PositionalValue<int> count = CountAlbums.Query<PositionalValue<int>>(cnn);
Mapping slot rules
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Field)]
sealed class DbPrefixAttribute : Attribute, INameComparerMaker
{
public INameComparer MakeComparer(Type type, ref INameComparer current, object[] attributes, object? member)
=> new NameComparer("db_" + current.GetDefaultName());
}
public record Album([DbPrefix] int Id, string Title);
Multi-row mapping
ConstructorInfo seed = typeof(HashSet<>).GetConstructor(Type.EmptyTypes)
?? throw new InvalidOperationException("HashSet constructor was not found.");
MethodInfo add = typeof(HashSet<>).GetMethod(nameof(HashSet<int>.Add))
?? throw new InvalidOperationException("HashSet.Add was not found.");
TypeParsingInfo.AddOrSet(typeof(HashSet<>), new MultiRowTypeParsingInfo(seed, add, null));
public record Tag(int Id, string Name) : IDbReadable;
static readonly QueryCommand GetTags = new("SELECT TagId AS Id, Name FROM tags ORDER BY TagId");
HashSet<Tag> tags = GetTags.Query<HashSet<Tag>>(cnn);
Complete result parser
Complete result parser example