第三章:快速入门与环境配置
3.1 开发环境准备
3.1.1 必要的开发工具
| 工具 | 要求 | 说明 |
|---|---|---|
| Visual Studio | 2019/2022 | 推荐使用最新版本 |
| .NET SDK | 2.0 - 8.0 | 根据项目目标框架选择 |
| NuGet | 内置 | 包管理工具 |
| SQL Server / MySQL / 其他 | 任意版本 | 开发用数据库 |
3.1.2 .NET版本与NuGet包对应关系
| 目标框架 | NuGet包名 | 版本 |
|---|---|---|
| .NET 6.0+ | PWMIS.SOD | 6.0+ |
| .NET 5/.NET Core/.NET 4.x | PDF.NET.SOD | 7.0 |
| .NET 2.0 - 4.x | PDF.NET.SOD | 6.x及以下 |
3.1.3 数据库支持
SOD框架内置支持以下数据库:
| 数据库 | 内置/扩展 | providerName |
|---|---|---|
| SQL Server | 内置 | SqlServer |
| Access | 内置 | Access |
| Oracle | 内置 | Oracle |
| SQL CE | 内置 | SqlCe |
| OleDb | 内置 | OleDb |
| ODBC | 内置 | Odbc |
扩展支持的数据库:
| 数据库 | NuGet包 | providerName |
|---|---|---|
| MySQL | PDF.NET.SOD.MySQL.Provider | PWMIS.DataProvider.Data.MySQL,PWMIS.MySqlClient |
| PostgreSQL | PDF.NET.SOD.PostgreSQL.Provider | PWMIS.DataProvider.Data.PostgreSQL,PWMIS.PostgreSQLClient |
| SQLite | PDF.NET.SOD.SQLite.Provider | PWMIS.DataProvider.Data.SQLite,PWMIS.SQLiteClient |
| 达梦 | PWMIS.SOD.DaMeng.Provider | PWMIS.DataProvider.Data.Dameng,PWMIS.DamengClient |
| 人大金仓 | PWMIS.SOD.Kingbase.Provider | PWMIS.DataProvider.Data.Kingbase,PWMIS.KingbaseClient |
3.2 创建第一个SOD项目
3.2.1 创建控制台项目
使用Visual Studio:
- 打开Visual Studio
- 选择”创建新项目”
- 选择”控制台应用”模板
- 设置项目名称,如:
SODDemo - 选择目标框架(推荐.NET 6.0或更高版本)
使用命令行:
# 创建.NET 6.0控制台项目
dotnet new console -n SODDemo -f net6.0
# 进入项目目录
cd SODDemo
3.2.2 安装NuGet包
使用包管理器控制台:
# .NET 6.0及以上版本
Install-Package PWMIS.SOD
# .NET 5及以下版本
Install-Package PDF.NET.SOD
使用命令行:
# .NET 6.0及以上版本
dotnet add package PWMIS.SOD
# .NET 5及以下版本
dotnet add package PDF.NET.SOD
使用NuGet包管理器界面:
- 右键项目 → “管理NuGet程序包”
- 搜索”PWMIS.SOD”或”PDF.NET.SOD”
- 安装最新版本
3.2.3 配置数据库连接
在项目中创建或编辑appsettings.json(.NET Core/5+)或app.config(.NET Framework):
.NET Core/5+项目(appsettings.json):
{
"ConnectionStrings": {
"Default": "Server=.;Database=SODDemo;Trusted_Connection=True;TrustServerCertificate=True"
}
}
然后在代码中配置:
// 设置连接字符串
MyDB.Instance.ConnectionString = "Server=.;Database=SODDemo;...";
MyDB.Instance.DataProvider = new SqlServer();
.NET Framework项目(app.config):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="local"
connectionString="Data Source=.;Initial Catalog=SODDemo;Integrated Security=True"
providerName="SqlServer"/>
</connectionStrings>
</configuration>
3.2.4 定义第一个实体类
创建User.cs文件:
using PWMIS.DataMap.Entity;
namespace SODDemo
{
// 方式1:定义接口类型(用于动态创建实体类)
public interface IUser
{
int ID { get; set; }
string Name { get; set; }
string Email { get; set; }
DateTime CreateTime { get; set; }
}
// 方式2:定义完整的实体类
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); }
}
public string Name
{
get { return getProperty<string>("Name"); }
set { setProperty("Name", value, 50); } // 字段长度50
}
public string Email
{
get { return getProperty<string>("Email"); }
set { setProperty("Email", value, 100); }
}
public DateTime CreateTime
{
get { return getProperty<DateTime>("CreateTime"); }
set { setProperty("CreateTime", value); }
}
}
}
3.2.5 创建数据上下文(可选)
如果需要使用Code First自动创建表:
using PWMIS.DataMap.Entity;
namespace SODDemo
{
public class DemoDbContext : DbContext
{
public DemoDbContext() : base("local") // 使用配置名"local"
{
}
protected override bool CheckAllTableExists()
{
// 检查并创建用户表
CheckTableExists<UserEntity>();
return true;
}
}
}
3.2.6 编写第一个程序
using System;
using PWMIS.DataProvider.Data;
using PWMIS.DataMap.Entity;
using PWMIS.Core;
namespace SODDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("=== SOD框架快速入门示例 ===\n");
// 1. 初始化数据上下文(自动创建表)
var context = new DemoDbContext();
Console.WriteLine("数据库初始化完成!\n");
// 2. 创建用户数据
var user = new UserEntity
{
Name = "张三",
Email = "zhangsan@example.com",
CreateTime = DateTime.Now
};
// 3. 插入数据
int insertResult = context.Add(user);
if (insertResult > 0)
{
Console.WriteLine($"插入成功!用户ID: {user.ID}");
}
// 4. 查询数据(使用OQL)
var queryUser = new UserEntity();
queryUser.Name = "张三";
var oql = OQL.From(queryUser)
.Select()
.Where(queryUser.Name)
.END;
var users = EntityQuery<UserEntity>.QueryList(oql);
Console.WriteLine($"\n查询到 {users.Count} 条记录:");
foreach (var u in users)
{
Console.WriteLine($" ID={u.ID}, Name={u.Name}, Email={u.Email}");
}
// 5. 更新数据
user.Email = "zhangsan_new@example.com";
int updateResult = context.Update(user);
Console.WriteLine($"\n更新结果:{updateResult} 行受影响");
// 6. 删除数据
int deleteResult = context.Remove(user);
Console.WriteLine($"删除结果:{deleteResult} 行受影响");
Console.WriteLine("\n=== 示例运行完成 ===");
Console.ReadKey();
}
}
}
3.3 使用AdoHelper直接操作数据库
3.3.1 创建AdoHelper实例
using PWMIS.DataProvider.Data;
// 方式1:从配置文件读取
AdoHelper db = MyDB.GetDBHelperByConnectionName("local");
// 方式2:读取最后一个配置
AdoHelper db = MyDB.GetDBHelper();
// 方式3:直接创建
AdoHelper db = new SqlServer();
db.ConnectionString = "Data Source=.;Initial Catalog=SODDemo;Integrated Security=True";
3.3.2 执行SQL语句
AdoHelper db = MyDB.GetDBHelper();
// 创建表
string createTableSql = @"
CREATE TABLE TbUser (
ID INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(50),
Email NVARCHAR(100),
CreateTime DATETIME
)";
try
{
db.ExecuteNonQuery(createTableSql);
Console.WriteLine("表创建成功!");
}
catch (Exception ex)
{
Console.WriteLine($"表已存在或创建失败:{ex.Message}");
}
// 插入数据(参数化查询)
string insertSql = "INSERT INTO TbUser (Name, Email, CreateTime) VALUES (@Name, @Email, @CreateTime)";
var parameters = new IDataParameter[]
{
db.GetParameter("@Name", "张三"),
db.GetParameter("@Email", "zhangsan@example.com"),
db.GetParameter("@CreateTime", DateTime.Now)
};
int rows = db.ExecuteNonQuery(insertSql, CommandType.Text, parameters);
Console.WriteLine($"插入 {rows} 行");
// 查询数据
string selectSql = "SELECT * FROM TbUser WHERE Name = @Name";
var queryParams = new IDataParameter[]
{
db.GetParameter("@Name", "张三")
};
DataSet ds = db.ExecuteDataSet(selectSql, CommandType.Text, queryParams);
DataTable dt = ds.Tables[0];
foreach (DataRow row in dt.Rows)
{
Console.WriteLine($"ID={row["ID"]}, Name={row["Name"]}");
}
3.3.3 微型ORM查询
// 使用占位符参数的简化查询
string sql = "SELECT ID, Name, Email FROM TbUser WHERE Name = {0}";
// 方式1:映射到匿名类型
var users = db.ExecuteMapper(sql, "张三")
.MapToList(reader => new
{
ID = reader.GetInt32(0),
Name = reader.GetString(1),
Email = reader.GetString(2)
});
// 方式2:映射到POCO类
var userList = db.QueryList<UserInfo>(sql, "张三");
// UserInfo是一个简单的POCO类
public class UserInfo
{
public int ID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
3.4 使用ORM进行CRUD操作
3.4.1 创建实体类对象
// 方式1:直接创建实体类实例
UserEntity user = new UserEntity();
user.Name = "张三";
user.Email = "zhangsan@example.com";
user.CreateTime = DateTime.Now;
// 方式2:使用接口动态创建
IUser iUser = EntityBuilder.CreateEntity<IUser>();
iUser.Name = "李四";
iUser.Email = "lisi@example.com";
3.4.2 插入数据
AdoHelper db = MyDB.GetDBHelper();
UserEntity user = new UserEntity
{
Name = "张三",
Email = "zhangsan@example.com",
CreateTime = DateTime.Now
};
// 方式1:使用EntityQuery
int result = EntityQuery<UserEntity>.Instance.Insert(user, db);
Console.WriteLine($"插入成功,自增ID: {user.ID}");
// 方式2:使用DbContext
var context = new DemoDbContext();
context.Add(user);
3.4.3 查询数据
// 查询单个对象
UserEntity queryUser = new UserEntity();
queryUser.ID = 1;
var oql = OQL.From(queryUser)
.Select()
.Where(queryUser.ID)
.END;
UserEntity result = EntityQuery<UserEntity>.QueryObject(oql);
// 查询列表
UserEntity listQuery = new UserEntity();
listQuery.Name = "张"; // 模糊匹配
var listOql = OQL.From(listQuery)
.Select()
.Where(cmp => cmp.Comparer(listQuery.Name, "like", "张%"))
.OrderBy(order => order.Desc(listQuery.ID))
.END;
List<UserEntity> users = EntityQuery<UserEntity>.QueryList(listOql);
3.4.4 更新数据
UserEntity user = new UserEntity();
user.ID = 1; // 主键
// 先查询
var oql = OQL.From(user).Select().Where(user.ID).END;
UserEntity existUser = EntityQuery<UserEntity>.QueryObject(oql);
// 修改属性
existUser.Email = "new_email@example.com";
// 更新(只更新修改过的字段)
int result = EntityQuery<UserEntity>.Instance.Update(existUser, db);
// 批量更新
UserEntity updateUser = new UserEntity();
updateUser.Email = "batch@example.com"; // 要更新的值
var batchOql = OQL.From(updateUser)
.Update(updateUser.Email)
.Where(cmp => cmp.Comparer(updateUser.Name, "like", "张%"))
.END;
int affected = EntityQuery<UserEntity>.ExecuteOql(batchOql, db);
3.4.5 删除数据
UserEntity user = new UserEntity();
user.ID = 1;
// 方式1:根据主键删除
int result = EntityQuery<UserEntity>.Instance.Delete(user, db);
// 方式2:使用OQL条件删除
var deleteOql = OQL.From(user)
.Delete()
.Where(cmp => cmp.Property(user.Name) == "张三")
.END;
int affected = EntityQuery<UserEntity>.ExecuteOql(deleteOql, db);
// 方式3:使用DbContext
var context = new DemoDbContext();
context.Remove(user);
3.5 使用GOQL简化查询
GOQL(Generic OQL)是OQL的泛型版本,更加简洁:
using PWMIS.Core.Extensions;
// 简单查询
var users = OQL.FromObject<UserEntity>()
.Select()
.Where((cmp, u) => cmp.Property(u.Name) == "张三")
.END
.ToList();
// 带条件和排序的查询
var pageUsers = OQL.FromObject<UserEntity>()
.Select(s => new object[] { s.ID, s.Name, s.Email })
.Where((cmp, u) => cmp.Property(u.CreateTime) >= DateTime.Today)
.OrderBy((order, u) => order.Desc(u.ID))
.Limit(10, 1) // 分页
.ToList();
// 使用接口类型查询
var iUsers = OQL.FromObject<IUser>()
.Select()
.Where((cmp, u) => cmp.Comparer(u.Name, "like", "张%"))
.ToList();
3.6 完整示例项目
3.6.1 项目结构
SODDemo/
├── Program.cs # 主程序
├── Entities/
│ ├── UserEntity.cs # 用户实体
│ └── OrderEntity.cs # 订单实体
├── DataAccess/
│ └── DemoDbContext.cs # 数据上下文
├── Services/
│ └── UserService.cs # 业务逻辑层
├── app.config # 配置文件
└── SODDemo.csproj # 项目文件
3.6.2 完整代码示例
UserEntity.cs:
using PWMIS.DataMap.Entity;
using System;
namespace SODDemo.Entities
{
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); }
}
public string Name
{
get { return getProperty<string>("Name"); }
set { setProperty("Name", value, 50); }
}
public string Email
{
get { return getProperty<string>("Email"); }
set { setProperty("Email", value, 100); }
}
public int Status
{
get { return getProperty<int>("Status"); }
set { setProperty("Status", value); }
}
public DateTime CreateTime
{
get { return getProperty<DateTime>("CreateTime"); }
set { setProperty("CreateTime", value); }
}
}
}
DemoDbContext.cs:
using PWMIS.DataMap.Entity;
using SODDemo.Entities;
namespace SODDemo.DataAccess
{
public class DemoDbContext : DbContext
{
public DemoDbContext() : base("local")
{
}
protected override bool CheckAllTableExists()
{
CheckTableExists<UserEntity>();
return true;
}
}
}
UserService.cs:
using System;
using System.Collections.Generic;
using PWMIS.DataProvider.Data;
using PWMIS.DataMap.Entity;
using SODDemo.Entities;
namespace SODDemo.Services
{
public class UserService
{
private readonly AdoHelper _db;
public UserService()
{
_db = MyDB.GetDBHelper();
}
// 添加用户
public int AddUser(string name, string email)
{
var user = new UserEntity
{
Name = name,
Email = email,
Status = 1,
CreateTime = DateTime.Now
};
EntityQuery<UserEntity>.Instance.Insert(user, _db);
return user.ID;
}
// 根据ID获取用户
public UserEntity GetUser(int id)
{
var user = new UserEntity { ID = id };
var oql = OQL.From(user).Select().Where(user.ID).END;
return EntityQuery<UserEntity>.QueryObject(oql, _db);
}
// 获取所有用户
public List<UserEntity> GetAllUsers()
{
var user = new UserEntity();
var oql = OQL.From(user)
.Select()
.Where(cmp => cmp.Property(user.Status) == 1)
.OrderBy(order => order.Desc(user.ID))
.END;
return EntityQuery<UserEntity>.QueryList(oql, _db);
}
// 更新用户邮箱
public bool UpdateEmail(int id, string newEmail)
{
var user = GetUser(id);
if (user == null) return false;
user.Email = newEmail;
return EntityQuery<UserEntity>.Instance.Update(user, _db) > 0;
}
// 删除用户
public bool DeleteUser(int id)
{
var user = new UserEntity { ID = id };
return EntityQuery<UserEntity>.Instance.Delete(user, _db) > 0;
}
// 分页查询
public List<UserEntity> GetUsersByPage(int pageIndex, int pageSize, out int totalCount)
{
var user = new UserEntity();
var oql = OQL.From(user)
.Select()
.Where(cmp => cmp.Property(user.Status) == 1)
.OrderBy(order => order.Desc(user.ID))
.END;
oql.Limit(pageSize, pageIndex, true); // true表示同时计算总数
var list = EntityQuery<UserEntity>.QueryList(oql, _db);
totalCount = oql.PageWithAllRecordCount;
return list;
}
}
}
Program.cs:
using System;
using SODDemo.DataAccess;
using SODDemo.Services;
namespace SODDemo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("=== SOD框架完整示例 ===\n");
// 初始化数据库
var context = new DemoDbContext();
Console.WriteLine("数据库初始化完成!\n");
// 创建服务
var userService = new UserService();
// 1. 添加用户
Console.WriteLine("--- 添加用户 ---");
int id1 = userService.AddUser("张三", "zhangsan@example.com");
int id2 = userService.AddUser("李四", "lisi@example.com");
int id3 = userService.AddUser("王五", "wangwu@example.com");
Console.WriteLine($"添加了3个用户,ID分别为: {id1}, {id2}, {id3}\n");
// 2. 查询单个用户
Console.WriteLine("--- 查询用户 ---");
var user = userService.GetUser(id1);
Console.WriteLine($"查询到用户: ID={user.ID}, Name={user.Name}, Email={user.Email}\n");
// 3. 查询所有用户
Console.WriteLine("--- 所有用户列表 ---");
var allUsers = userService.GetAllUsers();
foreach (var u in allUsers)
{
Console.WriteLine($" ID={u.ID}, Name={u.Name}, Email={u.Email}");
}
Console.WriteLine();
// 4. 更新用户
Console.WriteLine("--- 更新用户邮箱 ---");
bool updated = userService.UpdateEmail(id1, "zhangsan_new@example.com");
Console.WriteLine($"更新结果: {(updated ? "成功" : "失败")}\n");
// 5. 分页查询
Console.WriteLine("--- 分页查询 ---");
var pageUsers = userService.GetUsersByPage(1, 2, out int totalCount);
Console.WriteLine($"总记录数: {totalCount}, 当前页记录数: {pageUsers.Count}");
foreach (var u in pageUsers)
{
Console.WriteLine($" ID={u.ID}, Name={u.Name}");
}
Console.WriteLine();
// 6. 删除用户
Console.WriteLine("--- 删除用户 ---");
bool deleted = userService.DeleteUser(id3);
Console.WriteLine($"删除用户 {id3} 结果: {(deleted ? "成功" : "失败")}\n");
Console.WriteLine("=== 示例运行完成 ===");
Console.ReadKey();
}
}
}
3.7 常见问题与解决方案
3.7.1 连接字符串配置问题
问题:找不到连接配置
解决:确保app.config或appsettings.json配置正确,并且配置文件已复制到输出目录。
<!-- app.config 需要在配置正确的节点下 -->
<configuration>
<connectionStrings>
<add name="local" connectionString="..." providerName="SqlServer"/>
</connectionStrings>
</configuration>
3.7.2 数据库提供程序问题
问题:无法加载数据库提供程序
解决:
- 安装对应的NuGet包
- 确保providerName格式正确
<!-- 扩展提供程序的格式 -->
<add name="mysql"
connectionString="Server=localhost;Database=test;Uid=root;Pwd=123456;"
providerName="PWMIS.DataProvider.Data.MySQL,PWMIS.MySqlClient"/>
3.7.3 实体类映射问题
问题:查询结果为空或字段值为null
解决:
- 检查TableName是否正确
- 检查属性名与字段名是否匹配
- 确认getProperty/setProperty中的字段名
// 检查映射配置
public class UserEntity : EntityBase
{
public UserEntity()
{
TableName = "TbUser"; // 确保表名正确
}
public string Name
{
get { return getProperty<string>("Name"); } // 确保字段名正确
set { setProperty("Name", value, 50); }
}
}
3.7.4 自增ID未回填
问题:插入后实体类的ID属性为0
解决:确保设置了IdentityName
public UserEntity()
{
TableName = "TbUser";
IdentityName = "ID"; // 必须设置自增字段名
PrimaryKeys.Add("ID"); // 添加主键
}
3.8 本章小结
本章介绍了SOD框架的快速入门内容:
- 开发环境准备:安装必要的工具和NuGet包
- 创建项目:使用VS或命令行创建项目
- 配置连接:配置数据库连接字符串
- 定义实体类:创建继承EntityBase的实体类
- CRUD操作:使用EntityQuery和OQL进行数据操作
- GOQL简化:使用泛型OQL简化代码
通过本章的学习,你应该能够使用SOD框架完成基本的数据库操作。在接下来的章节中,我们将深入学习实体类映射、OQL查询语言等高级特性。
下一章预告:第四章将深入讲解SOD实体类的定义、元数据映射机制以及高级映射技巧。