02-框架架构与核心组件

news/2025/11/29 13:42:49/文章来源:https://www.cnblogs.com/znlgis/p/19286241

第二章:框架架构与核心组件

2.1 整体架构设计

2.1.1 分层架构

SOD框架采用经典的分层架构设计,从底层到顶层依次为:

┌───────────────────────────────────────────────────────────────┐
│                       表示层 (Presentation)                    │
│    ┌─────────────────┐  ┌─────────────────────────────────┐  │
│    │  PWMIS.Windows  │  │         PWMIS.Web               │  │
│    │  WinForm控件    │  │         WebForm控件              │  │
│    └─────────────────┘  └─────────────────────────────────┘  │
├───────────────────────────────────────────────────────────────┤
│                       业务逻辑层 (Business Logic)              │
│    ┌─────────────────────────────────────────────────────┐   │
│    │                    DbContext                         │   │
│    │           数据上下文(可选,用于Code First)           │   │
│    └─────────────────────────────────────────────────────┘   │
├───────────────────────────────────────────────────────────────┤
│                       数据映射层 (Data Mapping)                │
│   ┌───────────┐  ┌─────────────┐  ┌───────────────────┐     │
│   │ SQL-MAP   │  │    ORM      │  │  EntityContainer  │     │
│   │ DBMapper  │  │EntityQuery  │  │    数据容器        │     │
│   └───────────┘  └─────────────┘  └───────────────────┘     │
├───────────────────────────────────────────────────────────────┤
│                       实体层 (Entity Layer)                    │
│   ┌─────────────────────────────────────────────────────────┐│
│   │                    EntityBase                           ││
│   │    实体类基类(动态属性、元数据映射、状态追踪)           ││
│   └─────────────────────────────────────────────────────────┘│
├───────────────────────────────────────────────────────────────┤
│                    数据访问层 (Data Access Layer)              │
│   ┌─────────────────────────────────────────────────────────┐│
│   │                     AdoHelper                           ││
│   │         抽象数据访问辅助类(数据库无关的API)            ││
│   └─────────────────────────────────────────────────────────┘│
├───────────────────────────────────────────────────────────────┤
│                   数据提供程序层 (Data Provider Layer)         │
│  ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌─────────┐    │
│  │SqlServer│ │ MySQL  │ │ Oracle │ │PostgreSQL││ SQLite │    │
│  └────────┘ └────────┘ └────────┘ └────────┘ └─────────┘    │
│  ┌────────┐ ┌────────┐ ┌────────┐                           │
│  │  达梦  │ │人大金仓 │ │ Access │  ...更多数据库...          │
│  └────────┘ └────────┘ └────────┘                           │
└───────────────────────────────────────────────────────────────┘

2.1.2 核心设计模式

SOD框架运用了多种经典的设计模式:

抽象工厂模式 (Abstract Factory)

用于创建不同数据库的数据访问提供程序:

// 根据配置自动创建对应数据库的AdoHelper
AdoHelper db = MyDB.GetDBHelper();  // 自动识别数据库类型

单例模式 (Singleton)

EntityQuery采用单例模式,避免重复创建:

// 获取单例实例
var eq = EntityQuery<UserEntity>.Instance;

建造者模式 (Builder)

OQL使用链式调用的建造者模式:

var oql = OQL.From(user).Select(user.ID, user.Name)  // 构建SELECT.Where(user.Status)          // 构建WHERE.OrderBy(user.ID)            // 构建ORDER BY.END;                        // 完成构建

策略模式 (Strategy)

不同数据库的SQL生成策略:

// 框架内部根据数据库类型选择不同的分页策略
// SqlServer: ROW_NUMBER()
// MySQL: LIMIT
// Oracle: ROWNUM
oql.Limit(10, 1);  // 自动适配不同数据库

2.2 AdoHelper:数据访问核心

2.2.1 AdoHelper的设计理念

AdoHelper是SOD框架的数据访问核心,它是一个抽象类,提供了与具体数据库无关的数据访问API。这种设计使得上层代码不需要关心底层使用的是什么数据库。

public abstract class AdoHelper
{// 执行非查询SQLpublic abstract int ExecuteNonQuery(string sql, CommandType cmdType, IDataParameter[] paras);// 执行查询返回DataSetpublic abstract DataSet ExecuteDataSet(string sql, CommandType cmdType, IDataParameter[] paras);// 执行查询返回DataReaderpublic abstract IDataReader ExecuteReader(string sql, CommandType cmdType, IDataParameter[] paras);// 执行查询返回标量值public abstract object ExecuteScalar(string sql, CommandType cmdType, IDataParameter[] paras);// 获取数据库参数对象public abstract IDataParameter GetParameter(string name, object value);// ... 更多抽象方法
}

2.2.2 创建AdoHelper实例

SOD框架提供了多种方式创建AdoHelper实例:

// 方式1:根据连接名称创建(推荐)
AdoHelper db = MyDB.GetDBHelperByConnectionName("local");// 方式2:使用最后一个连接配置
AdoHelper db = MyDB.GetDBHelper();// 方式3:直接实例化具体的数据库提供程序
AdoHelper db = new SqlServer();
db.ConnectionString = "Data Source=.;Initial Catalog=MyDB;...";// 方式4:根据配置字符串动态创建
AdoHelper db = AdoHelper.CreateHelper("local");

2.2.3 核心方法详解

ExecuteNonQuery - 执行非查询操作

// 执行INSERT/UPDATE/DELETE等操作
string sql = "UPDATE User SET Status=@Status WHERE ID=@ID";
IDataParameter[] paras = new IDataParameter[] {db.GetParameter("@Status", 1),db.GetParameter("@ID", 100)
};
int affectedRows = db.ExecuteNonQuery(sql, CommandType.Text, paras);

ExecuteDataSet - 返回数据集

// 查询返回DataSet
string sql = "SELECT * FROM User WHERE DeptId=@DeptId";
var paras = new[] { db.GetParameter("@DeptId", 1) };
DataSet ds = db.ExecuteDataSet(sql, CommandType.Text, paras);
DataTable dt = ds.Tables[0];

ExecuteScalar - 返回单个值

// 查询记录数
string sql = "SELECT COUNT(*) FROM User WHERE Status=1";
int count = Convert.ToInt32(db.ExecuteScalar(sql));

ExecuteMapper - 微型ORM映射

// 直接映射到对象列表
string sql = "SELECT ID,Name,Status FROM User WHERE DeptId={0}";
var users = db.ExecuteMapper(sql, 1).MapToList(reader => new User {ID = reader.GetInt32(0),Name = reader.GetString(1),Status = reader.GetInt32(2)});

2.2.4 事务支持

// 简单事务
db.BeginTransaction();
try
{db.ExecuteNonQuery("INSERT INTO ...");db.ExecuteNonQuery("UPDATE ...");db.Commit();
}
catch
{db.Rollback();throw;
}// 使用Session管理连接(推荐)
db.OpenSession();
try
{db.BeginTransaction();// 执行多个操作...db.Commit();
}
finally
{db.CloseSession();
}

2.3 EntityBase:实体类基类

2.3.1 设计思想

EntityBase是SOD框架所有实体类的基类,它实现了"充血实体类"模型,具有以下特性:

  1. 动态属性存储:属性值存储在内部字典中
  2. 状态追踪:记录哪些属性被修改过
  3. 元数据映射:动态定义表名、主键、字段映射
  4. 索引器访问:支持通过字符串名称访问属性

2.3.2 核心成员

public abstract class EntityBase
{// 表名public string TableName { get; set; }// 标识字段(自增字段)public string IdentityName { get; set; }// 主键集合public List<string> PrimaryKeys { get; }// 属性名集合public string[] PropertyNames { get; }// 获取属性值protected T getProperty<T>(string propertyName);// 设置属性值protected void setProperty(string propertyName, object value, int length = 0);// 索引器访问public object this[string propertyName] { get; set; }// 设置外键关系protected void SetForeignKey<T>(string foreignKeyName);// 获取表名public string GetTableName();// 判断属性是否被修改public bool PropertyChangedList(string propertyName);
}

2.3.3 实体类定义示例

public class UserEntity : EntityBase
{public UserEntity(){// 设置映射的表名TableName = "TbUser";// 设置自增标识字段IdentityName = "ID";// 设置主键PrimaryKeys.Add("ID");}// 自增主键public int ID{get { return getProperty<int>("ID"); }set { setProperty("ID", value); }}// 普通字段,指定长度为50public string Name{get { return getProperty<string>("Name"); }set { setProperty("Name", value, 50); }}// 可空类型字段public DateTime? Birthday{get { return getProperty<DateTime?>("Birthday"); }set { setProperty("Birthday", value); }}
}

2.3.4 动态特性的应用

运行时修改表名(分表)

UserEntity user = new UserEntity();
// 根据用户ID进行分表
int tableIndex = userId % 10;
user.TableName = $"TbUser_{tableIndex}";var result = OQL.From(user).Select().Where(user.ID).END.ToObject();
// 实际查询的是 TbUser_0, TbUser_1 等表

运行时修改主键

UserEntity user = new UserEntity();
user.PrimaryKeys.Clear();
user.PrimaryKeys.Add("LoginName");  // 用登录名作为主键进行删除user.LoginName = "zhangsan";
EntityQuery<UserEntity>.Instance.Delete(user);
// 生成: DELETE FROM TbUser WHERE LoginName=@LoginName

2.3.5 索引器的妙用

UserEntity user = new UserEntity();// 使用索引器设置值
user["Name"] = "张三";
user["Status"] = 1;// 使用索引器获取值
object name = user["Name"];// 动态排序场景
string sortField = "CreateTime";  // 来自前端参数
var oql = OQL.From(user).Select().OrderBy(user[sortField], "desc")  // 动态排序.END;

2.4 OQL:ORM查询语言

2.4.1 OQL的设计理念

OQL(ORM Query Language)是SOD框架独创的ORM查询语言,设计目标是:

  1. 接近SQL语法:让有SQL经验的开发者零学习成本
  2. 类型安全:编译期检查,避免运行时错误
  3. 链式调用:流畅的API设计
  4. 多表支持:支持复杂的关联查询

2.4.2 OQL vs SQL

-- SQL
SELECT ID, Name, Status 
FROM User 
WHERE DeptId = 1 AND Status = 1 
ORDER BY CreateTime DESC
LIMIT 10 OFFSET 0
// OQL
UserEntity user = new UserEntity();
user.DeptId = 1;
user.Status = 1;var oql = OQL.From(user).Select(user.ID, user.Name, user.Status).Where(user.DeptId, user.Status).OrderBy(order => order.Desc(user.CreateTime)).END;
oql.Limit(10, 1);

2.4.3 OQL的语法结构

OQL.From(entity)           // 指定查询的实体对象[.InnerJoin/LeftJoin]   // 可选:关联查询.Select(...)            // SELECT子句.Where(...)             // WHERE子句[.GroupBy(...)]         // 可选:分组[.Having(...)]          // 可选:分组条件.OrderBy(...)           // 排序.END                    // 结束构建// 分页(在END之后调用)
oql.Limit(pageSize, pageIndex);

2.4.4 OQL vs GOQL

GOQL(Generic OQL)是OQL的泛型简化版本,适用于单表查询:

// OQL方式 - 需要先创建实体对象
UserEntity user = new UserEntity();
user.Name = "张三";
var oql = OQL.From(user).Select().Where(user.Name).END;// GOQL方式 - 无需创建实体对象,使用Lambda表达式
var goql = OQL.FromObject<UserEntity>().Select().Where((cmp, u) => cmp.Property(u.Name) == "张三").END;// 执行查询
var users = goql.ToList();

2.5 EntityQuery:实体查询执行器

2.5.1 职责与功能

EntityQuery是将OQL翻译为SQL并执行的核心类,主要职责:

  1. 执行OQL查询
  2. 将结果映射到实体对象
  3. 执行实体的增删改操作

2.5.2 核心方法

// 查询单个对象
UserEntity user = EntityQuery<UserEntity>.QueryObject(oql, db);// 查询对象列表
List<UserEntity> users = EntityQuery<UserEntity>.QueryList(oql, db);// 查询带子实体的对象列表
List<OrderEntity> orders = EntityQuery<OrderEntity>.QueryListWithChild(oql, db);// 执行OQL(用于UPDATE/DELETE)
int affected = EntityQuery<UserEntity>.ExecuteOql(oql, db);// 插入实体
EntityQuery<UserEntity>.Instance.Insert(user, db);// 更新实体
EntityQuery<UserEntity>.Instance.Update(user, db);// 删除实体
EntityQuery<UserEntity>.Instance.Delete(user, db);

2.5.3 批量操作

// 批量插入
List<UserEntity> users = new List<UserEntity>() { ... };
foreach(var user in users)
{EntityQuery<UserEntity>.Instance.Insert(user, db);
}// 批量更新(使用OQL)
UserEntity user = new UserEntity();
user.Status = 0;  // 设置要更新的值var oql = OQL.From(user).Update(user.Status).Where(cmp => cmp.Property(user.DeptId) == 10).END;int affected = EntityQuery<UserEntity>.ExecuteOql(oql, db);
// 生成: UPDATE TbUser SET Status=0 WHERE DeptId=10

2.6 EntityContainer:数据容器

2.6.1 设计目的

EntityContainer用于处理多表关联查询的结果映射,当查询涉及多个表时,可以将结果映射到不同的类型。

2.6.2 使用场景

// 多表关联查询
OrderEntity order = new OrderEntity();
UserEntity user = new UserEntity();var oql = OQL.From(order).InnerJoin(user).On(order.UserId, user.ID).Select().Where(cmp => cmp.Property(order.Status) == 1).END;// 使用EntityContainer映射结果
EntityContainer ec = new EntityContainer(oql, db);// 映射到匿名类型
var list = ec.MapToList(() => new {OrderId = order.ID,OrderName = order.Name,UserName = user.Name,UserPhone = user.Phone
});// 映射到指定类型
var orderList = ec.MapToList<OrderEntity>();
var userList = ec.MapToList<UserEntity>();

2.6.3 复杂映射示例

// 查询订单及用户信息,进行计算和格式化
var list = ec.MapToList(() => new OrderViewModel {OrderId = order.ID,OrderNo = order.OrderNo,TotalPrice = order.Price.ToString("C"),  // 货币格式UserName = user.Name,UserAge = DateTime.Now.Year - user.Birthday.Year,  // 计算年龄StatusText = order.Status == 1 ? "已完成" : "进行中"
});

2.7 DbContext:数据上下文

2.7.1 Code First支持

DbContext提供Code First开发模式支持,可以根据实体类自动创建数据表:

public class MyDbContext : DbContext
{public MyDbContext() : base("local")  // 连接配置名{}protected override bool CheckAllTableExists(){// 检查并创建表CheckTableExists<UserEntity>();CheckTableExists<OrderEntity>();// 创建表后初始化(如创建索引)InitializeTable<OrderEntity>("CREATE INDEX idx_userId ON {0}(UserId)");return true;}
}

2.7.2 CRUD操作

var context = new MyDbContext();// 添加
context.Add(user);// 批量添加
context.AddList(users);// 更新
context.Update(user);// 删除
context.Remove(user);// 事务
bool success = context.Transaction(ctx => {ctx.Add(order);ctx.AddList(orderItems);
}, out string errorMessage);

2.8 组件协作流程

2.8.1 查询流程

用户代码 → OQL构建器 → OQL对象↓EntityQuery.QueryList()↓SQL生成(根据AdoHelper类型)↓AdoHelper.ExecuteReader()↓结果映射(反射或表达式树)↓返回实体对象列表

2.8.2 插入流程

用户代码 → 实体对象↓EntityQuery.Insert()↓生成INSERT SQL(排除未修改字段)↓AdoHelper.ExecuteNonQuery()↓获取自增ID(如果有)↓回填实体对象的标识字段

2.8.3 更新流程

用户代码 → 修改实体属性↓EntityQuery.Update()↓生成UPDATE SQL(只更新修改过的字段)↓AdoHelper.ExecuteNonQuery()↓返回受影响行数

2.9 本章小结

本章详细介绍了SOD框架的核心架构和主要组件:

  1. AdoHelper:抽象数据访问层,屏蔽数据库差异
  2. EntityBase:充血实体类基类,支持动态映射和状态追踪
  3. OQL/GOQL:类SQL的ORM查询语言,链式调用
  4. EntityQuery:执行查询和增删改操作
  5. EntityContainer:处理多表查询的结果映射
  6. DbContext:提供Code First和事务支持

理解这些核心组件的设计思想和协作方式,是掌握SOD框架的基础。在后续章节中,我们将深入学习每个组件的具体使用方法。


下一章预告:第三章将介绍如何快速入门SOD框架,包括环境配置、项目搭建和第一个示例程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/980772.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

03-快速入门与环境配置

第三章:快速入门与环境配置 3.1 开发环境准备 3.1.1 必要的开发工具工具 要求 说明Visual Studio 2019/2022 推荐使用最新版本.NET SDK 2.0 - 8.0 根据项目目标框架选择NuGet 内置 包管理工具SQL Server / MySQL / 其…

01-框架概述与设计理念

第一章:SOD框架概述与设计理念 1.1 SOD框架简介 1.1.1 什么是SOD框架 SOD框架(SQL-MAP、ORM、Data Controls)是一个拥有超过15年历史的国产开源企业级数据应用开发框架。它诞生于2006年,最初名为PDF.NET框架,后来…

小红书代运营公司TOP5权威推荐:资质齐全品牌甄选,助力企业

当下,小红书以2.6亿月活用户、70%以上的年轻消费群体成为企业精准获客的核心阵地。2024年数据显示,小红书企业号数量同比增长65%,但超30%的企业因代运营选择不当遭遇流量陷阱:内容同质化导致笔记零曝光、投流ROI不…

电力电缆厂家TOP5权威推荐:甄选质量过硬、客户反馈佳的供应

电缆作为能源传输与工业运行的血管,其品质直接决定项目安全与长期价值。2024年数据显示,我国电缆市场规模超1.2万亿元,但58%的工程安全事故与劣质电缆相关,30%的采购方因选型不当导致返工损失。面对非标泛滥、适配…

CF1666C-Connect the Points

CF1666C-Connect the Points 题目大意 给你平面上的三个点,用垂直于坐标轴的线段连接这三个点,使得线段总长度最小。 题解 考虑 \(x\) 坐标中间的那个点,建立一条覆盖三个点纵坐标的竖直的线段。将两侧的两个点通过…

打磨细节质感,成就卓越代码——《代码大全2》第六部分读后感

打磨细节质感,成就卓越代码——《代码大全2》第六部分读后感 《代码大全2》第六部分“代码构建中的细节”聚焦编程实践的微观层面,从变量命名、注释风格、代码格式到控制结构优化、异常处理规范等细节入手,系统阐述…

哈尔滨精密轴承代理商综合实力TOP10排行榜

为了让榜单经得起推敲,我们联合黑龙江省机械工程学会,参照国际轴承协会(FAGMA)2025 年最新标准,花了两个月做实地调研。所有数据均经第三方机构 “中机检测” 验证,全程拒绝企业自报数据,这也是为啥能成为多家国…

2025年工业冷风机节能效率排行榜出炉,炼胶车间通风降温/制造业车间通风降温/机械厂车间降温/炼钢车间通风降温工业冷风机厂商选哪家

行业格局深度解析 随着制造业绿色转型加速,工业冷风机作为车间降温的关键设备,其节能效率成为企业采购的核心考量因素。据最新市场调研数据显示,2024年工业冷风机市场规模已达127亿元,同比增长18.3%。本文基于公开…

2025 年 11 月空调机组厂家最新推荐,实力品牌深度解析采购无忧之选!

2025 年全球商用空调机组市场需求持续攀升,规模预计突破 920 亿美元,同比增长 8.5%,但行业数据显示,42% 的采购方因品牌选择失误导致后期维护成本增加 30% 以上。为破解采购困境,本次推荐联合国际空气处理与制冷协…

3. vim上手 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

深耕代码质量,筑牢工程根基——《代码大全2》第四部分读后感

深耕代码质量,筑牢工程根基——《代码大全2》第四部分读后感 《代码大全2》第四部分“全面质量管理”以“构建高质量代码”为核心,从软件质量的本质、缺陷预防、测试策略到持续改进,系统拆解了代码从“可用”到“优…

2025年哈尔滨精密轴承厂家综合实力前十强排行榜

轴承的 “灵魂” 是精度,我们以 P 级精度(P2/P4/P5)量产能力为核心指标,参考数字化车间建设水平。像新哈精密轴承有黑龙江省数字化示范车间,哈轴集团能实现 P4 级轴承工业化量产,这类企业直接加分。一、选轴承像…

2025年空调机组厂家最新推荐,产能、专利、环保三维数据透视!

2025 年全球空调机组市场规模持续扩容,据行业测算同比增长 7.5%,但产品性能参差、适配性不足等问题仍困扰采购决策。本次推荐基于国际权威测评标准编制,测评流程严格遵循 ANSI/ASHRAE Standard 16-2016 检测规范,对…

2025年空调机组厂家最新推荐,组合式,直膨式净化,变风量,远程射流,转轮热回收空调机组公司测评

2025 冷年全球空调总出货规模达 2.21 亿台,同比增长 12.9%,但市场中 TOP6-8 长尾品牌均价下滑 22% 仍难提升份额,产品性能与可靠性差异显著。为破解采购决策难题,本次推荐依托国际权威测评体系编制,测评流程严格遵…

2025年度工部优选十大品牌排名:工部优选的十个领先品牌是什

工程行业的品牌选择向来是甲方、施工单位与设计院的核心痛点——虚假榜单充斥市场、低价内卷扰乱判断、跨平台调研消耗大量时间。作为工程行业生态服务平台的标杆,工部优选依托业主、设计院、总包的真实采购数据,发布…

2025年十大诚信且资质齐全的宅基地建房企业推荐,专业乡墅设

在乡村振兴的浪潮下,越来越多的人选择返乡建房,一栋安全可靠、设计合理的宅基地自建房,成为承载乡愁与家庭幸福的重要载体。然而,乡村建房市场鱼龙混杂,如何找到诚信可靠、资质齐全的宅基地建房企业,成为许多人的…

如何被更新的?就是[人工智能-大模型-122]:模型层 - RNN是通过神经元还是通过张量时间记录状态信息?时间状态信息

如何被更新的?就是[人工智能-大模型-122]:模型层 - RNN是通过神经元还是通过张量时间记录状态信息?时间状态信息pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; …

深入解析:SSH 密钥从 RSA 到 Ed25519

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

停止背诵 API:AI 时代,代码只是你的“外设”

时代的断层:从“精确记忆”到“模糊检索” 在很长一段时间里,编程被定义为一种对精确性有着变态要求的技能。 你需要像背字典一样记住 C 语言的标准库,你需要清楚地知道一个 API 的第三个参数传的是指针还是引用。那…

2025国产冻干机品牌TOP5权威推荐:实验室冻干设备甄选指

科研与医药领域中,冻干技术作为样品活性保存、工艺优化的核心支撑,需求持续攀升。2024年数据显示,国内实验室冻干机市场规模超30亿元,年增速35%,但42%的科研机构投诉集中在性能虚标、真空不稳、售后滞后三大问题—…