4501359eac
【问题】
主人反馈:base_device 后端无法保存数据到数据库(A3 设备同步静默不写但返回 200)。
【根因】
base_device.cs:266-274 NodeId 字段被误标:
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
[Key]
public int? NodeId { get; set; }
而 DeviceId 已经是主键+自增(line 23-29),产生 3 重故障:
1. SqlSugar INSERT 时同时跳过 DeviceId 和 NodeId,但数据库 NodeId INT NULL 不是 AUTO_INCREMENT
→ entity.NodeId=gatewayNodeId 被跳过,实际写 NULL/默认值
2. Updateable WHERE 子句变成 DeviceId=X AND NodeId=Y 双重主键匹配
→ NodeId 实际值与赋的值不一致时,Update 影响行数=0 静默失败
3. SqlSugar 异常被 SyncDevicesAsync catch 块吞掉,Controller 看不到具体原因
【修复】
1. base_device.cs:268-270 移除 [SugarColumn(IsPrimaryKey=true,IsIdentity=true)] 和 [Key]
NodeId 改为普通外键字段(只保留 Column/Editable)
2. gateway_nodesService.cs: SyncDevicesAsync 新增 INSERT try/catch + 详细日志
- 每条新增/更新打印 Adapter/SourceId/DeviceId/NodeId 便于定位
- 失败时记录 entity 完整字段值(Name/Cat/Grp)便于排查
- catch 块 LogError 后 throw,异常不再被吞
【验证】
dotnet build api_sqlsugar 0 错误 0 警告
【效果】
- Insertable 正常写入 entity.NodeId=gatewayNodeId 值
- Updateable WHERE 只用 DeviceId 单主键匹配
- 异常不再静默,Controller 会返回 500 + 具体异常信息,主人能从日志看到根因
296 lines
8.8 KiB
C#
296 lines
8.8 KiB
C#
/*
|
||
*代码由框架生成,任何更改都可能导致被代码生成器覆盖
|
||
*如果数据库字段发生变化,请在代码生器重新生成此Model
|
||
*/
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel.DataAnnotations;
|
||
using System.ComponentModel.DataAnnotations.Schema;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using SqlSugar;
|
||
using VolPro.Entity.SystemModels;
|
||
|
||
namespace VolPro.Entity.DomainModels
|
||
{
|
||
[Entity(TableCnName = "设备管理",TableName = "base_device",DetailTable = new Type[] { typeof(video_channel),typeof(iot_devicedata),typeof(iot_alarm)},DetailTableCnName = "视频通道,数据归档,告警记录",DBServer = "ServiceDbContext")]
|
||
public partial class base_device:ServiceEntity
|
||
{
|
||
/// <summary>
|
||
///设备ID
|
||
/// </summary>
|
||
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||
[Key]
|
||
[Display(Name ="设备ID")]
|
||
[Column(TypeName="int")]
|
||
[Editable(true)]
|
||
[Required(AllowEmptyStrings=false)]
|
||
public int DeviceId { get; set; }
|
||
|
||
/// <summary>
|
||
///设备名称
|
||
/// </summary>
|
||
[Display(Name ="设备名称")]
|
||
[MaxLength(100)]
|
||
[Column(TypeName="nvarchar(100)")]
|
||
[Editable(true)]
|
||
[Required(AllowEmptyStrings=false)]
|
||
public string DeviceName { get; set; }
|
||
|
||
/// <summary>
|
||
///来源适配器(类型:实例)
|
||
/// </summary>
|
||
[Display(Name ="来源适配器(类型:实例)")]
|
||
[MaxLength(50)]
|
||
[Column(TypeName="nvarchar(50)")]
|
||
[Editable(true)]
|
||
public string AdapterCode { get; set; }
|
||
|
||
/// <summary>
|
||
///源系统设备ID
|
||
/// </summary>
|
||
[Display(Name ="源系统设备ID")]
|
||
[MaxLength(100)]
|
||
[Column(TypeName="nvarchar(100)")]
|
||
[Editable(true)]
|
||
public string SourceId { get; set; }
|
||
|
||
/// <summary>
|
||
///设备种类(数据字典)
|
||
/// </summary>
|
||
[Display(Name ="设备种类(数据字典)")]
|
||
[MaxLength(50)]
|
||
[Column(TypeName="nvarchar(50)")]
|
||
[Editable(true)]
|
||
[Required(AllowEmptyStrings=false)]
|
||
public string DeviceCategory { get; set; }
|
||
|
||
/// <summary>
|
||
///设备分组(数据字典)
|
||
/// </summary>
|
||
[Display(Name ="设备分组(数据字典)")]
|
||
[MaxLength(20)]
|
||
[Column(TypeName="nvarchar(20)")]
|
||
[Editable(true)]
|
||
[Required(AllowEmptyStrings=false)]
|
||
public string DeviceGroup { get; set; }
|
||
|
||
/// <summary>
|
||
///所属点位ID
|
||
/// </summary>
|
||
[Display(Name ="所属点位ID")]
|
||
[Column(TypeName="int")]
|
||
[Editable(true)]
|
||
public int? PointId { get; set; }
|
||
|
||
/// <summary>
|
||
///是否父设备(数据字典)
|
||
/// </summary>
|
||
[Display(Name ="是否父设备(数据字典)")]
|
||
[MaxLength(20)]
|
||
[Column(TypeName="nvarchar(20)")]
|
||
[Editable(true)]
|
||
[Required(AllowEmptyStrings=false)]
|
||
public string IsParent { get; set; }
|
||
|
||
/// <summary>
|
||
///父设备ID(自引用,子设备挂父设备下)
|
||
/// </summary>
|
||
[Display(Name ="父设备ID(自引用,子设备挂父设备下)")]
|
||
[Column(TypeName="int")]
|
||
[Editable(true)]
|
||
public int? ParentDeviceId { get; set; }
|
||
|
||
/// <summary>
|
||
///在线状态(数据字典)
|
||
/// </summary>
|
||
[Display(Name ="在线状态(数据字典)")]
|
||
[MaxLength(20)]
|
||
[Column(TypeName="nvarchar(20)")]
|
||
[Editable(true)]
|
||
public string IsOnline { get; set; }
|
||
|
||
/// <summary>
|
||
///IP地址
|
||
/// </summary>
|
||
[Display(Name ="IP地址")]
|
||
[MaxLength(50)]
|
||
[Column(TypeName="nvarchar(50)")]
|
||
[Editable(true)]
|
||
public string IpAddress { get; set; }
|
||
|
||
/// <summary>
|
||
///端口
|
||
/// </summary>
|
||
[Display(Name ="端口")]
|
||
[Column(TypeName="int")]
|
||
[Editable(true)]
|
||
public int? Port { get; set; }
|
||
|
||
/// <summary>
|
||
///安装位置
|
||
/// </summary>
|
||
[Display(Name ="安装位置")]
|
||
[MaxLength(200)]
|
||
[Column(TypeName="nvarchar(200)")]
|
||
[Editable(true)]
|
||
public string Location { get; set; }
|
||
|
||
/// <summary>
|
||
///纬度
|
||
/// </summary>
|
||
[Display(Name ="纬度")]
|
||
[Column(TypeName="double")]
|
||
[Editable(true)]
|
||
public decimal? Lat { get; set; }
|
||
|
||
/// <summary>
|
||
///经度
|
||
/// </summary>
|
||
[Display(Name ="经度")]
|
||
[Column(TypeName="double")]
|
||
[Editable(true)]
|
||
public decimal? Lng { get; set; }
|
||
|
||
/// <summary>
|
||
///三维地图模型ID
|
||
/// </summary>
|
||
[Display(Name ="三维地图模型ID")]
|
||
[MaxLength(100)]
|
||
[Column(TypeName="nvarchar(100)")]
|
||
[Editable(true)]
|
||
public string MapModelId { get; set; }
|
||
|
||
/// <summary>
|
||
///模型缩放比例
|
||
/// </summary>
|
||
[Display(Name ="模型缩放比例")]
|
||
[Column(TypeName="decimal")]
|
||
[Editable(true)]
|
||
public decimal? MapModelScale { get; set; }
|
||
|
||
/// <summary>
|
||
///模型旋转角度(JSON)
|
||
/// </summary>
|
||
[Display(Name ="模型旋转角度(JSON)")]
|
||
[MaxLength(100)]
|
||
[Column(TypeName="nvarchar(100)")]
|
||
[Editable(true)]
|
||
public string MapModelRotation { get; set; }
|
||
|
||
/// <summary>
|
||
///适配器扩展数据JSON(Owl/MC4/门禁字段均存于此)
|
||
/// </summary>
|
||
[Display(Name ="适配器扩展数据JSON(Owl/MC4/门禁字段均存于此)")]
|
||
[Column(TypeName="nvarchar(max)")]
|
||
[Editable(true)]
|
||
public string ExtraData { get; set; }
|
||
|
||
/// <summary>
|
||
///上次同步时间
|
||
/// </summary>
|
||
[Display(Name ="上次同步时间")]
|
||
[Column(TypeName="datetime")]
|
||
[Editable(true)]
|
||
public DateTime? LastSyncTime { get; set; }
|
||
|
||
/// <summary>
|
||
///启用状态(数据字典)
|
||
/// </summary>
|
||
[Display(Name ="启用状态(数据字典)")]
|
||
[MaxLength(20)]
|
||
[Column(TypeName="nvarchar(20)")]
|
||
[Editable(true)]
|
||
public string Enable { get; set; }
|
||
|
||
/// <summary>
|
||
///备注
|
||
/// </summary>
|
||
[Display(Name ="备注")]
|
||
[MaxLength(500)]
|
||
[Column(TypeName="nvarchar(500)")]
|
||
[Editable(true)]
|
||
public string Remark { get; set; }
|
||
|
||
/// <summary>
|
||
///创建人ID
|
||
/// </summary>
|
||
[Display(Name ="创建人ID")]
|
||
[Column(TypeName="int")]
|
||
[Editable(true)]
|
||
public int? CreateID { get; set; }
|
||
|
||
/// <summary>
|
||
///创建人
|
||
/// </summary>
|
||
[Display(Name ="创建人")]
|
||
[MaxLength(50)]
|
||
[Column(TypeName="nvarchar(50)")]
|
||
[Editable(true)]
|
||
public string Creator { get; set; }
|
||
|
||
/// <summary>
|
||
///创建时间
|
||
/// </summary>
|
||
[Display(Name ="创建时间")]
|
||
[Column(TypeName="datetime")]
|
||
[Editable(true)]
|
||
public DateTime? CreateDate { get; set; }
|
||
|
||
/// <summary>
|
||
///修改人ID
|
||
/// </summary>
|
||
[Display(Name ="修改人ID")]
|
||
[Column(TypeName="int")]
|
||
[Editable(true)]
|
||
public int? ModifyID { get; set; }
|
||
|
||
/// <summary>
|
||
///修改人
|
||
/// </summary>
|
||
[Display(Name ="修改人")]
|
||
[MaxLength(50)]
|
||
[Column(TypeName="nvarchar(50)")]
|
||
[Editable(true)]
|
||
public string Modifier { get; set; }
|
||
|
||
/// <summary>
|
||
///修改时间
|
||
/// </summary>
|
||
[Display(Name ="修改时间")]
|
||
[Column(TypeName="datetime")]
|
||
[Editable(true)]
|
||
public DateTime? ModifyDate { get; set; }
|
||
|
||
/// <summary>
|
||
///所属网关节点ID
|
||
/// </summary>
|
||
[Display(Name ="所属网关节点ID")]
|
||
// V1.12.1 修复:NodeId 不是主键,只是一个外键字段。
|
||
// 之前误标 [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] + [Key],
|
||
// 会导致 SqlSugar INSERT 时跳过 NodeId(认为是自增)→ 数据库实际为 NULL,
|
||
// 传进来的 gatewayNodeId 永远写不进去;Update 时 WHERE 变成双主键匹配,
|
||
// 容易因 NodeId 实际值与赋的值不一致导致 Update 静默失败。
|
||
[Column(TypeName="int")]
|
||
[Editable(true)]
|
||
public int? NodeId { get; set; }
|
||
|
||
[Display(Name ="视频通道")]
|
||
[ForeignKey("DeviceId")][Navigate(NavigateType.OneToMany,nameof(DeviceId),nameof(DeviceId))]
|
||
public List<video_channel> video_channel { get; set; }
|
||
|
||
|
||
[Display(Name ="数据归档")]
|
||
[ForeignKey("DeviceId")][Navigate(NavigateType.OneToMany,nameof(DeviceId),nameof(DeviceId))]
|
||
public List<iot_devicedata> iot_devicedata { get; set; }
|
||
|
||
|
||
[Display(Name ="告警记录")]
|
||
[ForeignKey("DeviceId")][Navigate(NavigateType.OneToMany,nameof(DeviceId),nameof(DeviceId))]
|
||
public List<iot_alarm> iot_alarm { get; set; }
|
||
|
||
|
||
|
||
}
|
||
} |