目前 Camstar 开发主要分为两种:1、基于 Designer 的 CLF 编程;2、基于 C# 的程序编程。在 Designer 环境下的 CLF 可以通过(对象实例.字段)的方式快速访问数据,但 Designer 并不是完善的编程工具,不方便调试,没有语法校验等功能,开发效率较低。对于 C# 提供的各种类库,CLF 同样难以调用。而 C# 有强大的生态环境,工具齐全,类库丰富。
为了能在 C# 环境下更便捷地访问 Camstar 对象数据,本项目基于 ORM 构建只读数据访问层(Opcenter.Execution.Data)。本库不开放 SaveChanges 写库。
可选 ORM 很多,综合考虑后选择支持懒加载与对象关系配置的 EF Core 作为首选。
一、项目位置
backend/Opcenter.Execution.Data
配套说明(均在本项目内):
README.md:结构与用法总览Docs/repository-api-matrix.md:仓储查询 API 与 CancellationToken 约定
二、使用示例
支持 Oracle 与 SQL Server。通过本项目扩展方法 AddOpcenterExDbServices 注册。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| services.AddOpcenterExDbServices(options => { options.ConnectionString = "..."; options.DatabaseType = DatabaseType.SqlServer; options.Schema = "CamstarPRD_SCHEMA"; });
public class ExampleService(INamedDataObjectRepository<Factory> factories) { public async Task<string?> GetEnterpriseNameAsync(string factoryName, CancellationToken ct) { var factory = await factories.GetFirstByNameAsync(factoryName, ct); return factory?.Enterprise?.Name; } }
public class QueryService(OpcenterExDbClient db) { public Task<List<Factory>> ListByEnterpriseAsync(string enterpriseName, CancellationToken ct) => db.RunQueryAsync<Factory, List<Factory>>(async (q, token) => await q .Where(f => f.Enterprise != null && f.Enterprise.Name == enterpriseName) .OrderBy(f => f.Name) .ToListAsync(token), ct); }
|
三、实体类示例
命名空间与 DbSet 以当前代码为准;实体与 IEntityTypeConfiguration 常同文件 partial 声明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| namespace Opcenter.Execution.Data.Entities { [Table("FACTORY")] public class Factory : NamedDataObject { [Column("CDOTYPEID")] public new int? CDOTypeId { get; set; }
[Column("CHANGECOUNT")] public new int? ChangeCount { get; set; }
[Column("DESCRIPTION")] public new string? Description { get; set; }
[ForeignKey("ENTERPRISEID")] public virtual Enterprise? Enterprise { get; set; }
[Key] [Column("FACTORYID")] public new string? InstanceID { get; set; }
[Column("FACTORYNAME")] public new string? Name { get; set; }
[Column("NOTES")] public new string? Notes { get; set; }
[ForeignKey("PRINTQUEUEID")] public virtual PrintQueue? PrintQueue { get; set; } } }
namespace Opcenter.Execution.Data.DbContexts { using Opcenter.Execution.Data.Entities;
public partial class OpcenterExDbContext : DbContext { public DbSet<Factory> Factories { get; set; } }
public class FactoryEntityTypeConfiguration : IEntityTypeConfiguration<Factory> { public void Configure(EntityTypeBuilder<Factory> builder) { } } }
|
四、注意事项
- 只读:
OpcenterExDbContext 在存在 Added/Modified/Deleted 时会拒绝 SaveChanges / SaveChangesAsync;DI 默认 NoTracking。 - 查询分层:简单按名/条件用
IRepository / INamedDataObjectRepository / IRevisionedObjectRepository;跨实体复杂 LINQ 用 OpcenterExDbClient.RunQueryAsync;原生 SQL 表名经 QualifyTable 限定 schema。 - 数据库:SQL Server 与 Oracle 均支持;Oracle 需
Oracle.EntityFrameworkCore。 - 懒加载:客户端会启用代理懒加载;生产查询更推荐显式
Include / 投影,避免 N+1。
五、版本信息
当前Opcenter Execution版本为2504 Core
项目地址:https://github.com/LicoCode/Opcenter.Execution.Data