概念模型 → 逻辑模型完整转换步骤(C#/ 数据库开发通用流程)

概念模型 → 逻辑模型完整转换步骤(C#/数据库开发通用流程)

前置认知

  • 概念模型:纯业务ER,只有实体、属性、关系,无数据类型、无主键、无范式、无存储细节,客户/产品能看懂。
  • 逻辑模型:规范化程序实体,确定主键、属性、关系约束、消除数据冗余,只关注业务结构,不绑定数据库。

转换核心思路:拆解实体 → 完善属性 → 规范化主键 → 处理实体关系 → 范式去冗余 → 输出标准业务实体(C# Model)

一、完整6步转换流程

步骤1:提取所有业务实体,剔除无关描述

从概念ER图/需求文档里挑出独立业务对象,合并重复名词,删除描述性文字。
示例(林业系统概念模型原始描述)

系统有操作员,记录操作员姓名、登录密码;系统保存文件,每个文件归属文件夹;每次操作生成一条日志,日志记录操作人、操作内容。

提取实体:

  1. 操作员 Operator
  2. 文件夹 Folder
  3. 文件 File
  4. 操作日志 OperateLog

步骤2:给每个实体梳理全部属性,区分标识属性与普通属性

  1. 把概念里所有描述整理为实体属性;
  2. 区分两类属性:
    • 标识属性:能唯一区分每条数据(后期做主键)
    • 普通属性:业务描述信息
  3. 统一属性命名(英文驼峰,C#规范)

示例:操作员实体
概念属性:操作员编号、姓名、密码、创建时间
逻辑属性:OperatorId、OperatorName、Password、CreateTime

步骤3:为每个实体定义唯一主键(逻辑主键,无关自增)

概念模型没有主键,逻辑模型必须给每个实体分配唯一标识主键

  1. 优先业务主键(身份证、档案编号);
  2. 无天然唯一业务字段,新增代理主键 Id;
  3. 主键作用:程序内唯一区分对象,建立关联关系。

示例:

  • Operator:主键 OperatorId
  • OperateLog:主键 LogId

步骤4:转换实体间关系(一对一/一对多/多对多)

概念只写“谁和谁有关联”,逻辑模型要落地外键、导航关系:

  1. 一对多(最常见)
    一方主键,放到多方作为外键;C#中一方加集合导航属性,多方存外键字段。
    例:一个操作员多条日志
  • OperateLog 增加外键 OperatorId;
  • Operator 增加 List<OperateLog> 导航集合。
  1. 一对一
    任意一方存入对方主键作为外键。

  2. 多对多
    概念只写两者关联,逻辑模型必须拆成中间实体,两个外键分别指向双方主键。
    例:文件与标签多对多
    新增中间实体 FileTag,包含 FileId、TagId 两个外键。

步骤5:应用三大范式,消除数据冗余(逻辑模型核心规范)

这一步是区分“原始概念”和“规范逻辑模型”的关键:

  1. 第一范式:属性不可再拆分(不能一个字段存多个数据,如地址不分省市区)
  2. 第二范式:非主键字段完全依赖主键(不能部分依赖)
  3. 第三范式:非主键字段不依赖其他非主键字段(杜绝传递冗余)

反例(冗余设计,概念模型常见,逻辑层必须优化)
日志实体同时保存 OperatorId、OperatorName
问题:姓名属于操作员信息,存在传递依赖,修改姓名要改全部日志,冗余;
优化:日志只保留 OperatorId,姓名通过关联查询获取。

步骤6:补充业务约束,形成最终逻辑实体

只加业务层面约束(不加数据库存储约束):

  • 是否允许为空(业务必填/选填)
  • 字段取值范围、枚举(操作类型:新增/删除/修改)
  • 唯一约束(用户名不能重复)
    不添加:varchar长度、自增、索引、表名等物理信息。

最后输出:纯C#业务实体类(无任何ORM数据库特性标记)

二、完整转换实战案例

原始概念模型(文字版)

实体:操作员、操作日志
关系:一个操作员产生多条操作日志
属性:
操作员:编号、姓名、登录密码
日志:操作编号、操作人姓名、操作内容、操作时间

一步步转换

  1. 实体:Operator、OperateLog
  2. 梳理属性,发现冗余:日志存了操作人姓名
  3. 设置主键:OperatorId、LogId
  4. 处理一对多关系:日志增加外键 OperatorId,删除冗余 OperatorName
  5. 三范式校验:无传递依赖,无重复存储
  6. 补充业务约束:姓名、密码、操作内容不能为空

最终逻辑模型(C#实体,纯业务)

// 逻辑模型:无数据库相关标记
public class Operator
{
    // 主键
    public long OperatorId { get; set; }
    // 业务必填
    public string OperatorName { get; set; }
    public string Password { get; set; }
    public DateTime CreateTime { get; set; }
    // 一对多导航属性
    public List<OperateLog> OperateLogs { get; set; }
}

public class OperateLog
{
    // 主键
    public long LogId { get; set; }
    // 外键,关联操作员
    public long OperatorId { get; set; }
    public string Content { get; set; }
    public DateTime OperateTime { get; set; }
    // 单导航
    public Operator Operator { get; set; }
}

三、转换避坑要点

  1. 不要提前加入数据库细节
    逻辑阶段不写长度、自增、表名、索引,这些属于物理模型;
  2. 多对多一定要拆中间表
    概念模型可以简化描述,逻辑模型必须拆分为独立实体;
  3. 严格去冗余
    概念模型为了好理解会重复存储信息,逻辑模型必须按范式拆分;
  4. 主键统一规划
    全部实体统一使用代理Id,便于程序统一管理关联关系;
  5. 约束只区分业务必填,不设计数据库默认值。

四、极简记忆流程

概念(业务名词+关系)
→ 抽取实体属性
→ 设置主键
→ 转换关联、拆分多对多
→ 三范式消除冗余
→ 添加业务约束
= 标准逻辑模型(C#领域实体/Model)

posted @ 2026-06-16 14:53  人生就是修炼  阅读(7)  评论(0)    收藏  举报