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 toT0.<ColumnName>).DefaultValue— the default value.Index— the field's index in the fields collection.Fields— the owningRowFieldsBase.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?→Int32Fieldstring→StringFieldGender?(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.