深入了解ORMX的实体映射机制,学习如何定义实体类、配置表和列属性、处理数据类型和复杂映射。 关键字:实体映射, Table特性, Column特性, 类型映射, MongoDB映射
第三章:实体映射
3.1 实体类定义和映射
ORMX 使用特性(Attribute)来定义实体类与数据库表之间的映射关系。理解这些基础概念是使用 ORMX 的关键。
3.1.1 基本实体类定义
最简单的实体类定义只需要一个主键属性:
using JCode.ORMX.Attributes;
[Table(Name = "Users")]
public class User
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
映射规则:
- 类名默认映射到同名的数据库表(可以通过
[Table]特性修改) - 属性名默认映射到同名的数据库列(可以通过
[Column]特性修改)
3.1.2 Table 特性详解
[Table] 特性用于定义表级别的映射信息:
[Table(Name = "Users", Comment = "用户信息表")]
public class User
{
// ...
}
Table 特性参数:
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
| Name | string | 表名 | [Table(Name = "Users")] |
| Comment | string | 表注释 | [Table(Name = "Users", Comment = "用户表")] |
| Prefix | string | 表前缀 | [Table(Prefix = "app_")] |
示例:
// 完整的 Table 特性示例
[Table(Name = "Users", Comment = "用户信息表")]
public class User
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
public string Name { get; set; }
}
// 使用表前缀
[Table(Prefix = "sys_")]
public class User
{
// 实际表名将是 sys_User
}
3.1.3 Column 特性详解
[Column] 特性用于定义列级别的映射信息:
[Column(Name = "UserId", IsPrimaryKey = true, IsAutoIncrement = true, Comment = "用户ID")]
public int Id { get; set; }
Column 特性参数:
| 参数 | 类型 | 说明 | 默认值 | 示例 |
|---|---|---|---|---|
| Name | string | 列名 | 属性名 | [Column(Name = "UserId")] |
| Type | string | 数据库类型 | 自动推断 | [Column(Type = "VARCHAR(50)")] |
| Length | int | 字段长度 | 自动推断 | [Column(Length = 50)] |
| Nullable | bool | 是否可为空 | true | [Column(Nullable = false)] |
| IsPrimaryKey | bool | 是否为主键 | false | [Column(IsPrimaryKey = true)] |
| IsAutoIncrement | bool | 是否自增 | false | [Column(IsAutoIncrement = true)] |
| DefaultValue | string | 默认值 | null | [Column(DefaultValue = "0")] |
| Comment | string | 列注释 | null | [Column(Comment = "用户名")] |
3.1.4 完整的实体类示例
下面是一个完整的实体类定义示例:
using JCode.ORMX.Attributes;
using System;
[Table(Name = "Users", Comment = "用户信息表")]
public class User
{
[Column(Name = "UserId", IsPrimaryKey = true, IsAutoIncrement = true, Comment = "用户ID")]
public int Id { get; set; }
[Column(Name = "Username", Type = "VARCHAR(50)", Length = 50, Nullable = false, Comment = "用户名")]
public string Name { get; set; }
[Column(Name = "Email", Type = "VARCHAR(100)", Length = 100, Nullable = false, Comment = "邮箱地址")]
public string Email { get; set; }
[Column(Name = "Age", Type = "INT", Nullable = true, DefaultValue = "0", Comment = "年龄")]
public int Age { get; set; }
[Column(Name = "CreatedAt", Type = "DATETIME", Nullable = false, DefaultValue = "CURRENT_TIMESTAMP", Comment = "创建时间")]
public DateTime CreatedAt { get; set; }
[Column(Name = "IsActive", Type = "BOOLEAN", Nullable = false, DefaultValue = "1", Comment = "是否激活")]
public bool IsActive { get; set; }
}
3.2 数据类型映射
ORMX 会自动将 C# 类型映射到数据库类型:
| C# 类型 | SQLite | MySQL | PostgreSQL | SQL Server | MongoDB |
|---|---|---|---|---|---|
| int | INTEGER | INT | INTEGER | INT | Number |
| long | INTEGER | BIGINT | BIGINT | BIGINT | Number |
| decimal | REAL | DECIMAL | NUMERIC | DECIMAL | Number |
| double | REAL | DOUBLE | DOUBLE PRECISION | FLOAT | Number |
| string | TEXT | VARCHAR | VARCHAR | NVARCHAR | String |
| bool | INTEGER | TINYINT | BOOLEAN | BIT | Boolean |
| DateTime | TEXT | DATETIME | TIMESTAMP | DATETIME | Date |
| byte[] | BLOB | BLOB | BYTEA | VARBINARY | Binary |
自定义类型映射:
[Column(Type = "VARCHAR(50)")]
public string Name { get; set; }
[Column(Type = "DECIMAL(10,2)")]
public decimal Price { get; set; }
3.3 可空类型支持
ORMX 支持可空类型:
public class User
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
// 可空字符串
public string? Name { get; set; }
// 可空整数
public int? Age { get; set; }
// 可空日期
public DateTime? LastLoginAt { get; set; }
// 可空布尔
public bool? IsActive { get; set; }
}
3.4 枚举类型支持
ORMX 支持枚举类型:
public enum UserStatus
{
Active = 1,
Inactive = 2,
Suspended = 3
}
public class User
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
public string Name { get; set; }
public UserStatus Status { get; set; }
}
// 使用
var user = new User
{
Name = "张三",
Status = UserStatus.Active
};
userTable.Insert(user);
3.5 实践示例
3.5.1 定义订单实体
[Table(Name = "Orders", Comment = "订单表")]
public class Order
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true, Comment = "订单ID")]
public int Id { get; set; }
[Column(Nullable = false, Comment = "用户ID")]
public int UserId { get; set; }
[Column(Type = "DECIMAL(10,2)", Nullable = false, Comment = "订单金额")]
public decimal Amount { get; set; }
[Column(Type = "DATETIME", Nullable = false, DefaultValue = "CURRENT_TIMESTAMP", Comment = "创建时间")]
public DateTime CreatedAt { get; set; }
[Column(Nullable = false, DefaultValue = "0", Comment = "订单状态")]
public OrderStatus Status { get; set; }
}
public enum OrderStatus
{
Pending = 0,
Paid = 1,
Shipped = 2,
Completed = 3,
Cancelled = 4
}
3.5.2 定义产品实体
[Table(Name = "Products", Comment = "产品表")]
public class Product
{
[Column(IsPrimaryKey = true, Comment = "产品ID")]
public int Id { get; set; }
[Column(Type = "VARCHAR(100)", Nullable = false, Comment = "产品名称")]
public string Name { get; set; }
[Column(Type = "TEXT", Comment = "产品描述")]
public string Description { get; set; }
[Column(Type = "DECIMAL(10,2)", Nullable = false, Comment = "产品价格")]
public decimal Price { get; set; }
[Column(Nullable = false, DefaultValue = "0", Comment = "库存数量")]
public int Stock { get; set; }
[Column(Nullable = false, DefaultValue = "1", Comment = "是否上架")]
public bool IsActive { get; set; }
}
3.6 MongoDB 特定的实体映射
3.6.1 MongoDB 映射特点
MongoDB 作为文档数据库,有一些特殊的映射规则:
- _id 字段处理:MongoDB 自动为每个文档生成
_id字段,ORMX 会自动将实体的Id属性映射到_id字段 - 文档结构:MongoDB 支持嵌套文档和数组,ORMX 会自动处理复杂类型的映射
- 类型转换:ORMX 会自动处理 C# 类型与 MongoDB BSON 类型之间的转换
3.6.2 _id 字段映射
整数类型 ID:
[Table(Name = "Users")]
public class User
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; } // 映射到 MongoDB 的 _id 字段
public string Name { get; set; }
public string Email { get; set; }
}
字符串类型 ID:
[Table(Name = "Users")]
public class User
{
[Column(IsPrimaryKey = true)]
public string Id { get; set; } // 映射到 MongoDB 的 _id 字段
public string Name { get; set; }
public string Email { get; set; }
}
ObjectId 类型 ID:
using MongoDB.Bson;
[Table(Name = "Users")]
public class User
{
[Column(IsPrimaryKey = true)]
public ObjectId Id { get; set; } // 直接使用 MongoDB 的 ObjectId
public string Name { get; set; }
public string Email { get; set; }
}
3.6.3 复杂类型映射
嵌套对象:
[Table(Name = "Users")]
public class User
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
// 嵌套地址对象
public Address Address { get; set; }
}
// 地址类
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
}
数组类型:
[Table(Name = "Users")]
public class User
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
// 字符串数组
public List<string> Tags { get; set; }
// 对象数组
public List<PhoneNumber> Phones { get; set; }
}
// 电话号码类
public class PhoneNumber
{
public string Type { get; set; } // 例如:"home", "work"
public string Number { get; set; }
}
3.6.4 MongoDB 映射示例
完整的 MongoDB 实体示例:
using JCode.ORMX.Attributes;
using MongoDB.Bson;
[Table(Name = "Users", Comment = "用户信息表")]
public class User
{
[Column(IsPrimaryKey = true)]
public ObjectId Id { get; set; } // 使用 MongoDB ObjectId
[Column(Name = "username", Nullable = false, Comment = "用户名")]
public string Name { get; set; }
[Column(Name = "email", Nullable = false, Comment = "邮箱地址")]
public string Email { get; set; }
[Column(Name = "age", Comment = "年龄")]
public int Age { get; set; }
[Column(Name = "created_at", Comment = "创建时间")]
public DateTime CreatedAt { get; set; }
[Column(Name = "is_active", Comment = "是否激活")]
public bool IsActive { get; set; }
// 嵌套对象
public Address Address { get; set; }
// 数组
public List<string> Roles { get; set; }
public List<SocialProfile> SocialProfiles { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
}
public class SocialProfile
{
public string Platform { get; set; }
public string Username { get; set; }
public string Url { get; set; }
}
3.6.5 MongoDB 映射注意事项
_id 字段:
- 如果实体的
Id属性是整数类型,ORMX 会自动处理自增逻辑 - 如果实体的
Id属性是字符串类型,需要手动设置值 - 如果实体的
Id属性是ObjectId类型,MongoDB 会自动生成
- 如果实体的
嵌套对象:
- 嵌套对象会自动映射为 MongoDB 的嵌套文档
- 嵌套对象不需要
[Table]或[Column]特性
数组类型:
- 数组会自动映射为 MongoDB 的数组字段
- 支持基本类型数组和对象数组
类型转换:
- ORMX 会自动处理 C# 类型与 MongoDB BSON 类型之间的转换
- 对于复杂类型,会自动序列化为 BSON
字段命名:
- 默认情况下,属性名会映射为同名的字段
- 可以使用
[Column(Name = "field_name")]来自定义字段名 - MongoDB 通常使用蛇形命名法(snake_case)
3.6.6 实践示例:MongoDB 实体
用户实体(使用 ObjectId):
using JCode.ORMX.Attributes;
using MongoDB.Bson;
[Table(Name = "users")]
public class User
{
[Column(IsPrimaryKey = true)]
public ObjectId Id { get; set; }
[Column(Name = "username")]
public string Username { get; set; }
[Column(Name = "email")]
public string Email { get; set; }
[Column(Name = "password_hash")]
public string PasswordHash { get; set; }
[Column(Name = "created_at")]
public DateTime CreatedAt { get; set; }
[Column(Name = "updated_at")]
public DateTime UpdatedAt { get; set; }
public List<string> Roles { get; set; }
public Profile Profile { get; set; }
}
public class Profile
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Bio { get; set; }
public List<string> Interests { get; set; }
}
产品实体(使用整数 ID):
using JCode.ORMX.Attributes;
[Table(Name = "products")]
public class Product
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
[Column(Name = "name")]
public string Name { get; set; }
[Column(Name = "description")]
public string Description { get; set; }
[Column(Name = "price")]
public decimal Price { get; set; }
[Column(Name = "stock")]
public int Stock { get; set; }
[Column(Name = "created_at")]
public DateTime CreatedAt { get; set; }
public List<string> Categories { get; set; }
public List<Image> Images { get; set; }
public Dictionary<string, object> Attributes { get; set; }
}
public class Image
{
public string Url { get; set; }
public string Alt { get; set; }
public int Order { get; set; }
}
总结
实体映射是 ORMX 框架的核心功能之一,通过 [Table] 和 [Column] 特性,开发者可以灵活地定义 C# 实体类与数据库表之间的映射关系。ORMX 支持自动类型映射、可空类型、枚举类型等特性,能够满足大多数业务场景的需求。对于 MongoDB 这样的文档数据库,ORMX 提供了专门的映射支持,包括 _id 字段处理、嵌套对象和数组类型映射等。合理使用实体映射特性,可以大大简化数据访问层的开发工作。
扩展思考
随着业务复杂度的增加,如何处理跨表的数据关联和继承关系?是否需要引入值对象(Value Object)和聚合根(Aggregate Root)等 DDD 概念来优化实体设计?在微服务架构中,如何处理不同服务之间的实体共享和版本兼容问题?这些问题值得在深入使用 ORMX 后进一步思考。