Class ValueObjectTypeHandler<TSelf, TValue>
Namespace: AdCodicem.ValueObjects.Dapper
Assembly: AdCodicem.ValueObjects.Dapper.dll
Maps a value object to and from its underlying column value for Dapper.
public sealed class ValueObjectTypeHandler<TSelf, TValue> : SqlMapper.TypeHandler<TSelf>, SqlMapper.ITypeHandler where TSelf : struct, IValueObject<TSelf, TValue>
Type Parameters
TSelf
Value object type.
TValue
Underlying value type.
Inheritance
object ← SqlMapper.TypeHandler<TSelf> ← ValueObjectTypeHandler<TSelf, TValue>
Implements
SqlMapper.ITypeHandler
Inherited Members
SqlMapper.TypeHandler<TSelf>.SetValue(IDbDataParameter, TSelf), SqlMapper.TypeHandler<TSelf>.Parse(object), object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.ReferenceEquals(object?, object?), object.ToString()
Remarks
Reading uses the trusted factory, on the same reasoning as the Entity Framework Core converter: the rows come
from a database this application wrote through the validating factory, and read paths are hot. A column holding
text where the underlying type is not text, or the reverse, is the exception: the value object did not write it.
Text read into a value object whose underlying type is not uuid or uniqueidentifier one - is converted to
text, then validated through TryCreate.
A parameter declares the column a value object over Unicode = false as non-Unicode text of its
maximum length or, declaring none, of the value's own, and one declaring a maximum length alone as Unicode text of
that length. SQL Server then compares the parameter with the column as it is, with no implicit conversion of the
column to cost an index seek, and an Always Encrypted varchar column takes it. The size is never smaller than
the value, which both SqlClient and Npgsql would otherwise truncate.
A SQL NULL reads as null into an optional value object, TSelf?, and is refused
with a
For a member of a mapped type, or a parameter of the constructor it is mapped through, Dapper checks for a
NULL before it calls the handler, and never calls it: a required value object is left uninitialized,
default(TSelf), and nothing throws. A column that can be NULL belongs in a TSelf? member.
Every TValue, and NULL.
Methods
Parse(object)
Parse a database value back to a typed value
public override TSelf Parse(object value)
Parameters
value object
The value from the database
Returns
TSelf
The typed value
Exceptions
value is a SQL NULL, which a value object cannot hold, a value that cannot be
converted to TValue, or text, or a value converted to text, that the value object
refuses.
SetValue(IDbDataParameter, TSelf)
Assign the value of a parameter before a command executes
public override void SetValue(IDbDataParameter parameter, TSelf value)
Parameters
parameter IDbDataParameter
The parameter to configure
value TSelf
Parameter value
Remarks
The handler refuses to write a value the value object rejects, which a read would then trust: only an instance
equal to the default can hold one, since any other went through Create, and over a value type, where a
constructed zero equals the default too, validation tells a valid zero from a refused one. Dapper calls the
handler with the value object alone, whether the parameter is a TSelf or a
TSelf? holding one, so it cannot tell a column that takes a NULL from one that does not, and
refuses in both cases: a NULL is written from a TSelf? that holds nothing.
Exceptions
value equals default(TSelf) and holds a value the value object rejects.