关系映射
使用关系映射,使你在查询时会非常方便。你可以像 Entity Framework
的导航属性一样使用,也可以使用类似 Include 的方法带回关联的数据,因此,关系映射才是 ORM
最最核心的内容。
关系映射早期是使用 RelationshipAttribute
特性来标记是,它用于 assembly 中,指定两个实体类之间的关系。如下所示:
[assembly: RelationshipAttribute("products:order_details", typeof(Products), typeof(OrderDetails), "Id=>ProductID")]
[assembly: RelationshipAttribute("orders:order_details", typeof(Orders), typeof(OrderDetails), "OrderID=>OrderID")]
在 RelationshipAttribute
特性中,一般使用一对多方式进行映射,即 thisType 对应的是主表,otherType 对应的是子表,那么表达式采用 主键=>外键。当然有时候你可能会反着来,采用多对一的方式,那此时 thisType 对应的是子表,otherType 对应的是主表,表达式采用 外键<=主键。
现在,你不必要再指定 RelationshipAttribute
特性了,Fireasy 做了以下约定:只需你子表的外键的命名为 主表(单数形式)+Id,即可自动映射上。如下所示:
public class Products : LightEntity<Products>
{
[PropertyMapping(ColumnName = "product_id", IsPrimaryKey = true, GenerateType = IdentityGenerateType.AutoIncrement, IsNullable = false)]
public virtual int Id { get; set; }
}
public class Orders : LightEntity<Orders>
{
[PropertyMapping(ColumnName = "order_id", IsPrimaryKey = true, GenerateType = IdentityGenerateType.AutoIncrement, IsNullable = false)]
public virtual int Id { get; set; }
}
public class OrderDetails : LightEntity<OrderDetails>
{
[PropertyMapping(ColumnName = "product_id")]
public virtual int ProductId { get; set; }
[PropertyMapping(ColumnName = "order_id")]
public virtual int OrderId { get; set; }
public virtual Products Products { get; set; }
public virtual Orders Orders { get; set; }
}
如果无法遵守此约定,你也可以使用 RelationshipAssignAttribute
特性来指定所对应的主外键。如下所示:
public class Products : LightEntity<Products>
{
[PropertyMapping(ColumnName = "product_id", IsPrimaryKey = true, GenerateType = IdentityGenerateType.AutoIncrement, IsNullable = false)]
public virtual int Id { get; set; }
}
public class OrderDetails : LightEntity<OrderDetails>
{
/// <summary>
/// 商品ID。
/// </summary>
[PropertyMapping(ColumnName = "product_id")]
public virtual int ProdId { get; set; }
[RelationshipAssign(nameof(Products.Id), nameof(OrderDetails.ProdId))]
public virtual Products Products { get; set; }
}
这在一个子表同时关联了两个以上同一主表的情况下非常有用。如下所示:
public class Employees : LightEntity<Employees>
{
[PropertyMapping(ColumnName = "employee_id", IsPrimaryKey = true, GenerateType = IdentityGenerateType.AutoIncrement, IsNullable = false)]
public virtual int Id { get; set; }
}
public class Orders : LightEntity<Orders>
{
/// <summary>
/// 录入人ID。
/// </summary>
[PropertyMapping(ColumnName = "record_emp_id")]
public virtual int RecordEmpId { get; set; }
/// <summary>
/// 申请人ID。
/// </summary>
[PropertyMapping(ColumnName = "allpy_emp_id")]
public virtual int ApplyEmpId { get; set; }
/// <summary>
/// 审核人ID。
/// </summary>
[PropertyMapping(ColumnName = "audit_emp_id")]
public virtual int AuditEmpId { get; set; }
/// <summary>
/// 录入人。
/// </summary>
[RelationshipAssign(nameof(Employees.Id), nameof(Orders.RecordEmpId))]
public virtual Employees RecordEmployee { get; set; }
/// <summary>
/// 申请人。
/// </summary>
[RelationshipAssign(nameof(Employees.Id), nameof(Orders.ApplyEmpId))]
public virtual Employees ApplyEmployee { get; set; }
/// <summary>
/// 审核人。
/// </summary>
[RelationshipAssign(nameof(Employees.Id), nameof(Orders.AuditEmpId))]
public virtual Employees AuditEmployee { get; set; }
}