Using a StronglyTypedId record as an identity value for OrmLite?

StronglyTypedIds have been discussed and advocated for by a couple of well-known names in the C# development community.

Briefly, a StronglyTypedId is a specific instance of an abstract generic record implementing just a single Value autoproperty. The StronglyTypedId instance replaces the traditional int or guid Id in a class design, and prevents compile-time mistakes, for example, assigning an OderId to an OrderId

In a series of blog posts,Using C# 9 records as strongly-typed ids by Thomas Levesque, Mssr. Levesque implements custom converters of StronglyTypedIDs for serialization in System.Text.Json and in Newtonsoft, and implements converters for persisting/instantiating StronglyTypedIDs in Entity Framework 6 (EF6).

I would like to extend this work with serialization/deserialization using the ServiceStack Json serializer library, and persistence using OrmLite,

Superficially, persistence seems impossible as it is in opposition to ServiceStack’s design philosophy of “1 Poco to 1 Table”; however, the StronglyTypedID instance is simply a single Value autoproperty. This should map to the Id property of a Poco (and its persisted table).

I’ve done a good bit of searching in the ServiceStack OrmLite examples, to no avail. Before I spend more time on this - is it even theoretically possible to accomplish this?

public abstract record AbstractStronglyTypedId<TValue> {
// Generic Type Constraints are not able to restrict TValue to one of these four types: int, long, guid, or string[]. However, TValues other than these four can be detected at run time, and an exception raised, the very first time an improper instance of AbstractStronglyTypedId is created. This validation code is part of the constructor, and omitted for brevity.

  public TValue Value {get; init;}
}

public class MyPocoId : AbstractStronglyTypedId<int> {};

public class MyPoco {
[Identity]
[Autoincrement]
public MyPocoId Id {get; init}

// constructor omitted for brevity.
}

Should map to a table named Poco having a single column named Id with type int, and the data stored in the Id column should map to the inherited autoproperty MyPocoId.Value.

Mssr. Lavesque implements this in EF6 with an override of OnModelCreating for every EntityType having a property that derives from StronglytypedId, adding a converter and an Id mapping. C# 9 records as strongly-typed ids - Part 4: Entity Framework Core integration

Is this even remotely possible in ServiceStack OrmLite?

It definitely goes against OrmLite’s 1:1 mapping which causes an impedance mismatch where instead of your POCOs reflecting the RDBMS table structure it forces pushing artificial abstractions down to a ORM’s generic Data Abstraction Layer.

As such it’s not something I’d consider but I expect you should be able to implement similar semantics with a calculated property, e.g:

public class MyPoco 
{
    [Ignore]
    public MyPocoId MyPocoId { get; set; }

    [AutoIncrement]
    public int Id
    {
        get => MyPocoId.Value;
        set => MyPocoId = new(value);
    }
}

Alternatively you should also be able to accomplish it with a Type Converter where you can define the RDBMS column it maps to and how to convert it to/from and RDBMS value. Although I’d imagine doing this for every Id can get tedious.

Thank you for the (as always!) quick reply and suggestions.