Files
DMS/DMS.Application/Services/Database/VariableAppService.cs

286 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AutoMapper;
using DMS.Application.DTOs;
using DMS.Application.Interfaces;
using DMS.Application.Interfaces.Database;
using DMS.Core.Interfaces;
using DMS.Core.Models;
namespace DMS.Application.Services.Database;
/// <summary>
/// 变量应用服务,负责处理变量相关的业务逻辑。
/// 实现 <see cref="IVariableAppService"/> 接口。
/// </summary>
public class VariableAppService : IVariableAppService
{
private readonly IRepositoryManager _repoManager;
private readonly IMapper _mapper;
/// <summary>
/// 构造函数通过依赖注入获取仓储管理器和AutoMapper实例。
/// </summary>
/// <param name="repoManager">仓储管理器实例。</param>
/// <param name="mapper">AutoMapper 实例。</param>
public VariableAppService(IRepositoryManager repoManager, IMapper mapper)
{
_repoManager = repoManager;
_mapper = mapper;
}
/// <summary>
/// 异步根据ID获取变量数据传输对象。
/// </summary>
/// <param name="id">变量ID。</param>
/// <returns>变量数据传输对象。</returns>
public async Task<Variable> GetVariableByIdAsync(int id)
{
var variable = await _repoManager.Variables.GetByIdAsync(id);
return variable;
}
/// <summary>
/// 异步根据OPC UA NodeId获取变量数据传输对象。
/// </summary>
/// <param name="opcUaNodeId">OPC UA NodeId。</param>
/// <returns>变量数据传输对象。</returns>
public async Task<Variable?> GetVariableByOpcUaNodeIdAsync(string opcUaNodeId)
{
var variable = await _repoManager.Variables.GetByOpcUaNodeIdAsync(opcUaNodeId);
return variable ;
}
/// <summary>
/// 异步根据OPC UA NodeId列表获取变量数据传输对象列表。
/// </summary>
/// <param name="opcUaNodeIds">OPC UA NodeId列表。</param>
/// <returns>变量数据传输对象列表。</returns>
public async Task<List<Variable>> GetVariableByOpcUaNodeIdsAsync(List<string> opcUaNodeIds)
{
var variables = await _repoManager.Variables.GetByOpcUaNodeIdsAsync(opcUaNodeIds);
return variables;
}
/// <summary>
/// 异步获取所有变量数据传输对象列表。
/// </summary>
/// <returns>变量数据传输对象列表。</returns>
public async Task<List<Variable>> GetAllVariablesAsync()
{
var variables = await _repoManager.Variables.GetAllAsync();
return _mapper.Map<List<Variable>>(variables);
}
/// <summary>
/// 异步创建一个新变量(事务性操作)。
/// </summary>
/// <param name="variable">要创建的变量数据传输对象。</param>
public async Task<Variable> CreateVariableAsync(Variable variable)
{
try
{
await _repoManager.BeginTranAsync();
var addedVariable = await _repoManager.Variables.AddAsync(variable); await _repoManager.CommitAsync();
return _mapper.Map<Variable>(addedVariable);
}
catch (Exception ex)
{
await _repoManager.RollbackAsync();
throw new ApplicationException($"创建变量时发生错误,操作已回滚,错误信息:{ex.Message}", ex);
}
}
/// <summary>
/// 异步更新一个已存在的变量(事务性操作)。
/// </summary>
/// <param name="variable">要更新的变量数据传输对象。</param>
public async Task<int> UpdateVariableAsync(Variable variable)
{
try
{
await _repoManager.BeginTranAsync();
var existingVariable = await _repoManager.Variables.GetByIdAsync(variable.Id);
if (existingVariable == null)
{
throw new ApplicationException($"Variable with ID {variable.Id} not found.");
}
_mapper.Map(variable, existingVariable);
int res = await _repoManager.Variables.UpdateAsync(variable);
await _repoManager.CommitAsync();
return res;
}
catch (Exception ex)
{
await _repoManager.RollbackAsync();
throw new ApplicationException($"更新变量时发生错误,操作已回滚,错误信息:{ex.Message}", ex);
}
}
/// <summary>
/// 异步批量更新变量(事务性操作)。
/// </summary>
/// <param name="variables">要更新的变量数据传输对象列表。</param>
/// <returns>受影响的行数。</returns>
/// <exception cref="ApplicationException">如果更新变量时发生错误。</exception>
public async Task<int> UpdateVariablesAsync(List<Variable> variables)
{
try
{
await _repoManager.BeginTranAsync();
int totalAffected = 0;
foreach (var variable in variables)
{
var existingVariable = await _repoManager.Variables.GetByIdAsync(variable.Id);
if (existingVariable == null)
{
throw new ApplicationException($"Variable with ID {variable.Id} not found.");
}
_mapper.Map(variable, existingVariable);
int res = await _repoManager.Variables.UpdateAsync(existingVariable);
totalAffected += res;
}
await _repoManager.CommitAsync();
return totalAffected;
}
catch (Exception ex)
{
await _repoManager.RollbackAsync();
throw new ApplicationException($"批量更新变量时发生错误,操作已回滚,错误信息:{ex.Message}", ex);
}
}
/// <summary>
/// 异步删除一个变量(事务性操作)。
/// </summary>
/// <param name="id">要删除变量的ID。</param>
/// <returns>如果删除成功则为 true否则为 false。</returns>
/// <exception cref="InvalidOperationException">如果删除变量失败。</exception>
/// <exception cref="ApplicationException">如果删除变量时发生其他错误。</exception>
public async Task<bool> DeleteVariableAsync(int id)
{
try
{
await _repoManager.BeginTranAsync();
var variable = await _repoManager.Variables.GetByIdAsync(id);
if (variable == null)
{
throw new InvalidOperationException($"删除变量失败变量ID:{id}请检查变量Id是否存在");
}
var delRes = await _repoManager.Variables.DeleteAsync(variable);
if (delRes == 0)
{
throw new InvalidOperationException($"删除变量失败变量ID:{id}请检查变量Id是否存在");
}
await _repoManager.CommitAsync();
return true;
}
catch (Exception ex)
{
await _repoManager.RollbackAsync();
throw new ApplicationException($"删除变量时发生错误,操作已回滚,错误信息:{ex.Message}", ex);
}
}
/// <summary>
/// 异步批量删除变量(事务性操作)。
/// </summary>
/// <param name="ids">要删除的变量ID列表。</param>
/// <returns>如果删除成功则为 true否则为 false。</returns>
/// <exception cref="ArgumentException">如果ID列表为空或null。</exception>
/// <exception cref="ApplicationException">如果删除变量时发生错误。</exception>
public async Task<bool> DeleteVariablesAsync(List<int> ids)
{
if (ids == null || !ids.Any())
{
throw new ArgumentException("变量ID列表不能为空", nameof(ids));
}
try
{
await _repoManager.BeginTranAsync();
// 批量删除变量
// var deletedCount = await _repoManager.Variables.DeleteByIdsAsync(ids);
//
// // 检查是否所有变量都被成功删除
// if (deletedCount != ids.Count)
// {
// throw new InvalidOperationException($"删除变量失败:请求删除 {ids.Count} 个变量,实际删除 {deletedCount} 个变量");
// }
await _repoManager.CommitAsync();
return true;
}
catch (Exception ex)
{
await _repoManager.RollbackAsync();
throw new ApplicationException($"批量删除变量时发生错误,操作已回滚,错误信息:{ex.Message}", ex);
}
}
public async Task<List<Variable>> BatchImportVariablesAsync(List<Variable> variables)
{
try
{
var variableModels = _mapper.Map<List<Variable>>(variables);
var addedVariables = await _repoManager.Variables.AddAsync(variableModels);
return _mapper.Map<List<Variable>>(addedVariables);
}
catch (Exception ex)
{
throw new ApplicationException($"批量导入变量时发生错误,错误信息:{ex.Message}", ex);
}
}
public async Task<List<Variable>> FindExistingVariablesAsync(IEnumerable<Variable> variablesToCheck)
{
if (variablesToCheck == null || !variablesToCheck.Any())
{
return new List<Variable>();
}
var names = variablesToCheck.Select(v => v.Name).Where(n => !string.IsNullOrEmpty(n)).Distinct().ToList();
var s7Addresses = variablesToCheck.Select(v => v.S7Address).Where(a => !string.IsNullOrEmpty(a)).Distinct().ToList();
var opcUaNodeIds = variablesToCheck.Select(v => v.OpcUaNodeId).Where(id => !string.IsNullOrEmpty(id)).Distinct().ToList();
var allVariables = await _repoManager.Variables.GetAllAsync();
var existingVariablesFromDb = allVariables.Where(v =>
(names.Any() && !string.IsNullOrEmpty(v.Name) && names.Contains(v.Name)) ||
(s7Addresses.Any() && !string.IsNullOrEmpty(v.S7Address) && s7Addresses.Contains(v.S7Address)) ||
(opcUaNodeIds.Any() && !string.IsNullOrEmpty(v.OpcUaNodeId) && opcUaNodeIds.Contains(v.OpcUaNodeId)))
.ToList();
if (existingVariablesFromDb == null || !existingVariablesFromDb.Any())
{
return new List<Variable>();
}
var existingNames = new HashSet<string>(existingVariablesFromDb.Select(v => v.Name).Where(n => !string.IsNullOrEmpty(n)));
var existingS7Addresses = new HashSet<string>(existingVariablesFromDb.Select(v => v.S7Address).Where(a => !string.IsNullOrEmpty(a)));
var existingOpcUaNodeIds = new HashSet<string>(existingVariablesFromDb.Select(v => v.OpcUaNodeId).Where(id => !string.IsNullOrEmpty(id)));
var result = existingVariablesFromDb.Where(v =>
(names.Any() && !string.IsNullOrEmpty(v.Name) && names.Contains(v.Name)) ||
(s7Addresses.Any() && !string.IsNullOrEmpty(v.S7Address) && s7Addresses.Contains(v.S7Address)) ||
(opcUaNodeIds.Any() && !string.IsNullOrEmpty(v.OpcUaNodeId) && opcUaNodeIds.Contains(v.OpcUaNodeId)))
.ToList();
return result;
}
public async Task<Variable?> FindExistingVariableAsync(Variable variableToCheck)
{
if (variableToCheck == null)
{
return null;
}
// 创建一个包含单个元素的列表以便复用现有的逻辑
var variablesToCheck = new List<Variable> { variableToCheck };
var existingVariables = await FindExistingVariablesAsync(variablesToCheck);
// 如果找到了匹配的变量,返回第一个(也是唯一一个)
return existingVariables.FirstOrDefault();
}
}