Field Types

Every property in a row is backed by a field object of a specific type. The field type determines the C# value type, how the value is read from/written to the database, and how it's compared and serialized.

The Field Base Class

Field is the abstract base for all field types. It carries the metadata that makes a row work:

  • Name — the column name.
  • Type — the FieldType enum value (String, Int32, DateTime, etc.).
  • Caption — the display caption (local text).
  • Size — the column size (e.g. from [Size]).
  • Flags — the FieldFlags (NotNull, Insertable, Updatable, etc.).
  • Expression — the SQL expression (defaults to T0.<ColumnName>).
  • DefaultValue — the default value.
  • Index — the field's index in the fields collection.
  • Fields — the owning RowFieldsBase.
  • Join / JoinAlias — the join this field comes from, if any.
  • Origin — the origin alias for view fields.
  • MinSelectLevel — the minimum select level.
  • TextualField — the field used for display text.
  • ReadPermission / InsertPermission / UpdatePermission — field-level permissions.

Fields also provide the operations used by queries and services: AsObject/AsSqlValue (get/set values), ConvertValue, GetFromReader, IndexCompare, IsNull, Clone, and criteria operators (field == value, field > value, etc.).

Field Type Hierarchy

The concrete field types derive from a few generic bases:

  • GenericValueField<TValue> — base for value-type fields (int, long, decimal, DateTime, bool, Guid, etc.). It stores values via get/set delegates and supports enum types.
  • GenericClassField<TValue> — base for reference-type fields (string, byte[], Stream, etc.).
  • CustomClassField<TValue> — base for custom class-valued fields (List<T>, List<TRow>, JSON objects).
  • GenericField<TValue> — a general-purpose field for any value type.

Concrete Field Types

Field type C# value type Notes
StringField string Text columns
Int16Field short?
Int32Field int? Most common numeric field
Int64Field long?
SingleField float?
DoubleField double?
DecimalField decimal? Money/amounts; use [Scale] for precision
BooleanField bool?
DateTimeField DateTime? Date/time columns
DateTimeOffsetField DateTimeOffset?
DateOnlyField DateOnly? Date-only columns
TimeSpanField TimeSpan? Time columns
GuidField Guid?
ByteArrayField byte[] Binary data
StreamField Stream Stream data
EnumField<TEnum> TEnum? Enum columns (e.g. Gender?)
JsonField<TValue> TValue JSON-serialized object column
ListField<TValue> List<TValue> List of values (e.g. linking set)
RowListField<TRow> List<TRow> List of rows (e.g. master-detail)
RowField<TRow> TRow A single row value
VariantField object Dynamic/object value

Choosing the Right Field Type

The field type must match the property type exactly. For example:

public sealed class PersonRow : Row<PersonRow.RowFields>, IIdRow, INameRow
{
    [DisplayName("Person Id"), Identity, IdProperty]
    public int? PersonId { get => fields.PersonId[this]; set => fields.PersonId[this] = value; }

    [DisplayName("First Name"), Size(50), NotNull]
    public string FirstName { get => fields.FirstName[this]; set => fields.FirstName[this] = value; }

    [DisplayName("Gender")]
    public Gender? Gender { get => fields.Gender[this]; set => fields.Gender[this] = value; }

    public class RowFields : RowFieldsBase
    {
        public Int32Field PersonId;
        public StringField FirstName;
        public EnumField<Gender> Gender;
    }
}
  • int?Int32Field
  • stringStringField
  • Gender? (enum) → EnumField<Gender>

The [Size] attribute sets the field's Size (used for string length and numeric precision). The [Scale] attribute sets decimal precision.

Row and RowList Fields

  • RowField<TRow> holds a single row value.
  • RowListField<TRow> holds a list of rows. It's used for master-detail relations (e.g. a List<MovieCastRow> property with [MasterDetailRelation]) and is marked [NotMapped] by default.

These fields are typically [NotMapped] — they hold related data in memory but aren't columns in the row's own table.

See Also