Annotations provide metadata about your objects that allows DbExtensions generate commands for you. There are four attributes available for this purpose: TableAttribute, ColumnAttribute, AssociationAttribute and ComplexPropertyAttribute. The use of these attributes is always required, DbExtensions doesn’t infer any mapping between your objects and your database (no conventions).
TableAttribute
Use the TableAttribute to associate a class with a database table. If no name is specified, the class name is used as table name.
[Table(Name = "Products")]
public class Product {
...
}
ColumnAttribute
Use the ColumnAttribute to associate a property with a column in a database table. If no name is specified, the property name is used as column name.
[Column(IsPrimaryKey = true, IsDbGenerated = true)]
public int ProductID { get; set; }
AssociationAttribute
Use the AssociationAttribute to represent a database association, such as a foreign key relationship.
[Association(ThisKey = nameof(CategoryID))]
public Category Category { get; set; }
For one-to-many relationships, use a type that implements IEnumerable<T>, such as Collection<T>.
[Association(OtherKey = nameof(OrderDetail.ProductID))]
public Collection<OrderDetail> OrderDetails { get; } = new Collection<OrderDetail>();
The default for ThisKey and OtherKey, when not specified, is the type’s primary key properties.
For multi-column keys use a comma-separated list.
ComplexPropertyAttribute
Use the ComplexPropertyAttribute (starting v6.3) to group columns into a separate type. Some ORMs call these objects value objects. If no name is specified, the property name is used as base name, which is prepended to the column names as defined in the complex type.
Use the Separator property if the columns names use a naming convention that separate words, e.g. if the column names are Contact_Name
and Contact_Title
:
[ComplexProperty(Separator = "_")]
public Contact Contact { get; set; }
Tip: Automatic query mapping of complex properties
If you use $
as separator, then you can query your table using SqlBuilder with a simple SELECT *
and get your complex properties populated, as explained in Query Mapping.
Tip: Nesting complex types
You can nest the complex type definition in the type that uses it, to avoid polluting the namespace.