# 金蝶云星空企业版 C# 代码模式

## 数据访问模式

### 模式一：BusinessDataServiceHelper 查询

**适用场景：** 按主键或条件查询单个/多个实体

```csharp
// 按主键查询
DynamicObject entity = BusinessDataServiceHelper.LoadSingle(
    ctx, 
    primaryKey, 
    "PUR_POOrder"
);

// 按条件查询
QFilter filter = new QFilter("billno", "=", "PO-001");
DynamicObject[] entities = BusinessDataServiceHelper.Load(
    ctx, 
    "PUR_POOrder", 
    new QFilter[]{filter}
);

// 查询指定字段
string[] selectFields = new string[] { "id", "billno", "date", "amount" };
DynamicObject[] entities = BusinessDataServiceHelper.Load(
    ctx, 
    "PUR_POOrder", 
    selectFields, 
    new QFilter[]{filter}
);
```

### 模式二：DBUtils SQL 查询

**适用场景：** 复杂查询、报表查询、跨表查询

```csharp
// 简单查询
string sql = "SELECT FBILLNO, FDATE, FAMOUNT FROM T_PUR_POORDER WHERE FDOCUMENTSTATUS = 'C'";
DataSet ds = DBUtils.ExecuteDataSet(ctx, sql);

// 带参数查询
string sql = "SELECT * FROM T_PUR_POORDER WHERE FDATE >= @StartDate AND FDATE <= @EndDate";
List<SqlParam> parameters = new List<SqlParam>
{
    new SqlParam("@StartDate", startDate),
    new SqlParam("@EndDate", endDate)
};
DataSet ds = DBUtils.ExecuteDataSet(ctx, sql, parameters);

// 聚合查询
string sql = "SELECT FSUPPLIERID, SUM(FAMOUNT) AS TOTAL FROM T_PUR_POORDER GROUP BY FSUPPLIERID";
DataSet ds = DBUtils.ExecuteDataSet(ctx, sql);
```

---

## 事务处理模式

### 事务内操作

```csharp
// 使用 KDTransactionScope
using (KDTransactionScope scope = new KDTransactionScope())
{
    try
    {
        // 业务操作
        DBUtils.Execute(ctx, sql1);
        DBUtils.Execute(ctx, sql2);
        
        scope.Complete();
    }
    catch (Exception)
    {
        // 事务会自动回滚
        throw;
    }
}
```

---

## 异常处理模式

### 业务异常处理

```csharp
public void ProcessOrder(DynamicObject order)
{
    try
    {
        // 业务逻辑
        ValidateOrder(order);
        SaveOrder(order);
    }
    catch (KDException ex)
    {
        // 业务异常，记录日志并抛出
        Logger.Error("处理订单失败: " + ex.Message, ex);
        throw;
    }
    catch (Exception ex)
    {
        // 其他异常，包装为业务异常
        Logger.Error("系统异常: " + ex.Message, ex);
        throw new KDException("SYS001", "系统异常，请联系管理员", ex);
    }
}
```

### 校验异常处理

```csharp
public void ValidateOrder(DynamicObject order)
{
    List<string> errors = new List<string>();
    
    // 校验必填字段
    if (string.IsNullOrEmpty(order["FBillNo"] as string))
    {
        errors.Add("单据编号不能为空");
    }
    
    // 校验业务规则
    decimal amount = Convert.ToDecimal(order["FAmount"] ?? 0);
    if (amount <= 0)
    {
        errors.Add("金额必须大于零");
    }
    
    // 抛出校验异常
    if (errors.Count > 0)
    {
        throw new KDException("VALIDATE001", string.Join("; ", errors));
    }
}
```

---

## 日志记录模式

### 使用 Logger

```csharp
private static readonly ILog Logger = LogManager.GetLogger(typeof(OrderPlugin));

// 记录信息
Logger.Info("开始处理订单: " + billNo);

// 记录警告
Logger.Warn("订单金额较大: " + amount);

// 记录错误
Logger.Error("处理订单失败", exception);

// 调试日志
if (Logger.IsDebugEnabled)
{
    Logger.Debug("订单详情: " + order.ToString());
}
```

---

## 批量处理模式

### 批量查询

```csharp
// 分批查询大量数据
int batchSize = 1000;
int offset = 0;
List<DynamicObject> allResults = new List<DynamicObject>();

while (true)
{
    string sql = string.Format(
        "SELECT * FROM T_PUR_POORDER ORDER BY FID OFFSET {0} ROWS FETCH NEXT {1} ROWS ONLY",
        offset, batchSize
    );
    DataSet ds = DBUtils.ExecuteDataSet(ctx, sql);
    
    if (ds.Tables[0].Rows.Count == 0) break;
    
    foreach (DataRow row in ds.Tables[0].Rows)
    {
        // 处理每行数据
        allResults.Add(ConvertToEntity(row));
    }
    
    offset += batchSize;
}
```

### 批量更新

```csharp
// 使用事务批量更新
using (KDTransactionScope scope = new KDTransactionScope())
{
    foreach (var entity in entities)
    {
        string sql = "UPDATE T_PUR_POORDER SET FStatus = @Status WHERE FID = @ID";
        List<SqlParam> parameters = new List<SqlParam>
        {
            new SqlParam("@Status", "C"),
            new SqlParam("@ID", entity["FID"])
        };
        DBUtils.Execute(ctx, sql, parameters);
    }
    scope.Complete();
}
```
