.NET6下的Modbus通讯 和数据库记录
所用的包:<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>WinExe</OutputType><TargetFramework>net6.0-windows</TargetFramework><Nullable>enable</Null
·
所用的包:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<None Include="..\.editorconfig" Link=".editorconfig" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="NModbus4.NetCore" Version="2.0.1" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<None Update="VariableNode.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
通信库:
using Modbus.Device;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using thinger.DataConvertLib;
namespace EF6Demon
{
public class NModBusHelper
{
private TcpClient tcpClient = null;
private ModbusIpMaster master;
public bool Connect(string ip, string port)
{
try
{
tcpClient = new TcpClient();
tcpClient.Connect(IPAddress.Parse(ip), int.Parse(port));
master = ModbusIpMaster.CreateIp(tcpClient);
}
catch (Exception)
{
return false;
}
return tcpClient.Connected;
}
public bool Disconnect()
{
if (tcpClient != null)
{
tcpClient.Close();
return true;
}
else
{
return false;
}
}
public byte[] ReadKeepRegByteArr(string iAddress, string iLength)//偏移量,寄存器数量
{
try
{
ushort[] des = master.ReadHoldingRegisters(ushort.Parse(iAddress), ushort.Parse(iLength));
byte[] res = ByteArrayLib.GetByteArrayFromUShortArray(des);
return res;
}
catch (Exception)
{
return null;
}
}
public ushort[] ReadKeepRegUshort(string iAddress, string iLength)//偏移量,寄存器数量
{
try
{
ushort[] des = master.ReadHoldingRegisters(ushort.Parse(iAddress), ushort.Parse(iLength));
//byte[] res = ByteArrayLib.GetByteArrayFromUShortArray(des);
return des;
}
catch (Exception)
{
return null;
}
}
public List<float> AnalyseData_4x(ushort[] des, string iAddress)
{
int StartByte;
StartByte = int.Parse(iAddress) * 2;
List<float> floatArray = new List<float>();
byte[] byteArray = ByteArrayLib.GetByteArrayFromUShortArray(des);
for (int i = StartByte; i < byteArray.Length; i += 4)
{
floatArray.Add(FloatLib.GetFloatFromByteArray(byteArray, i));
}
return floatArray;
}
}
}
主程序:
using Microsoft.Extensions.Configuration;
using thinger.DataConvertLib;
namespace EF6Demon
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
this.Load += FrmMain_Load;
}
private ModelsResponsitory dbContext = new ModelsResponsitory();
private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
private IConfigurationRoot configRoot;
private CancellationTokenSource cts = new CancellationTokenSource();
ushort[] res;
string iAddress = "0";
string iLenth; //寄存器个数
private List<float> floatList = new List<float>();
private CancellationTokenSource cts1 = new CancellationTokenSource();
InsertDataSQLite objInsert = new InsertDataSQLite(10000);//10秒1次
private NModBusHelper objTcp;
private void FrmMain_Load(object? sender, EventArgs e)
{
//读取IP;
cfgBuilder.AddJsonFile("VariableNode.json", optional: true, reloadOnChange: true);
this.configRoot = cfgBuilder.Build();
CommonMethods.Ip = configRoot.GetSection("NodeClass:ModbusNode:ServerURL").Value;
CommonMethods.Port = configRoot.GetSection("NodeClass:ModbusNode:Port").Value;
CommonMethods.VarNum = configRoot.GetSection("NodeClass:ModbusNode:VarNum").Value;
//读取点表信息
//for (int i = 0; i < int.Parse(CommonMethods.VarNum); i++)
//{
// Variable variable = configRoot.GetSection($"NodeClass:ModbusNode:ModbusGroup:Variable:{i}").Get<Variable>();
// CommonMethods.AllVarList.Add(variable);
//}
this.iLenth = configRoot.GetSection("NodeClass:ModbusNode:ModbusGroup:Length").Value;
CommonMethods.ModbusTCPList = dbContext.GetAllVariable();
foreach (var item in CommonMethods.ModbusTCPList)
{
foreach (var item1 in item.ModbusNodes)
{
foreach (var item2 in item1.ModbusGroups)
{
CommonMethods.AllVarList.AddRange(item2.Variables);
}
}
}
InsertDataSQLite objInsert = new InsertDataSQLite(10000);//10秒1次
ModbusTCPInitialInfo();
Communication();
}
private void Communication()
{
if (CommonMethods.ModbusTCPList.Count() > 0)
{
foreach (var t in CommonMethods.ModbusTCPList)
{
foreach (var dev in t.ModbusNodes)
{
if (bool.Parse(dev.IsActive))
{
Task.Run(async () =>
{
while (!cts1.IsCancellationRequested)
{
if (CommonMethods.IsConnected)
{
await Task.Delay(500);
foreach (var gp in dev.ModbusGroups)
{
if (bool.Parse(gp.IsActive))
{
//读取数据
byte[] res = null;
if (int.Parse(gp.StoreArea) == 40000)
{
res = objTcp.ReadKeepRegByteArr(gp.Start, gp.Length);
}
if (res != null && res.Length == int.Parse(gp.Length) * 2)
{
CommonMethods.ErrorTimes = 0;
foreach (var variable in gp.Variables)
{
if (VerifyModbusAddress(false, variable.VarAddress, out int start, out int offset))
{
start -= int.Parse(gp.Start);
start *= 2;
// ABCD = 0,BADC = 1, CDAB = 2, DCBA = 3,
switch (variable.VarType)
{
case "Float":
variable.Value = FloatLib.GetFloatFromByteArray(res, start, DataFormat.ABCD).ToString();
break;
case "UShort":
variable.Value = UShortLib.GetUShortFromByteArray(res, start, DataFormat.ABCD).ToString();
break;
default:
break;
}
//包含就替换,否则就添加
if (CommonMethods.CurrentPLCValue.ContainsKey(variable.Name))
{
CommonMethods.CurrentPLCValue[variable.Name] = variable.Value;
}
else
{
CommonMethods.CurrentPLCValue.Add(variable.Name, variable.Value);
}
}
}
}
else
{
CommonMethods.ErrorTimes++;
if (CommonMethods.ErrorTimes >= int.Parse(dev.MaxErrorTimes))
{
CommonMethods.IsConnected = false;
}
}
}
}
}
else
{
if (!CommonMethods.FirstConnect)
{
//延时
await Task.Delay(int.Parse(dev.ReConnectTime));
objTcp?.Disconnect();
}
//第一次 连接
//初始化通信对象
objTcp = new NModBusHelper();
CommonMethods.IsConnected = objTcp.Connect(dev.ServerURL, dev.Port);
CommonMethods.FirstConnect = false;
await Task.Delay(200);
}
}
}, cts1.Token);
}
}
}
}
}
private void ModbusTCPInitialInfo()
{
foreach (var variable in CommonMethods.AllVarList)
{
if (!CommonMethods.CurrentPLCVariable.ContainsKey(variable.Name))
{
CommonMethods.CurrentPLCVariable.Add(variable.Name, variable);
}
else
{
CommonMethods.CurrentPLCVariable[variable.Name] = variable;
}
//存储的归档变量
if (bool.Parse(variable.ArchiveEnable))
{
CommonMethods.ArchiveVarList.Add(variable);
}
}
//归档变量, 用来查询实时数据, ArchiveEnable的数据要与配置文件SystemSet一致
foreach (var variable in CommonMethods.ArchiveVarList)
{
if (!CommonMethods.CurrentPLCNote.ContainsKey(variable.Name))
{
CommonMethods.CurrentPLCNote.Add(variable.Name, variable.Description);
}
else
{
CommonMethods.CurrentPLCNote[variable.Name] = variable.Description;
}
}
}
private bool VerifyModbusAddress(bool isBit, string address, out int start, out int offset)
{
if (isBit)
{
offset = 0;
return int.TryParse(address, out start);
}
else
{
if (address.Contains('.'))
{
string[] result = address.Split('.');
if (result.Length == 2)
{
bool val = true;
int res = 0;
val = val && int.TryParse(result[0], out res);
start = res;
val = val && int.TryParse(result[1], out res);
offset = res;
return val;
}
else
{
start = 0;
offset = 0;
return false;
}
}
else
{
offset = 0;
return int.TryParse(address, out start);
}
}
}
//设置ListBox
private void Addinfo(string info)
{
this.isInfo.Items.Insert(
0, DateTime.Now.ToString("HH:mm:ss") + " " + info + Environment.NewLine);
}
private void btnConn_Click(object sender, EventArgs e)
{
}
private NodeClass nodeClass = new NodeClass();
private ModbusNode modbusNode = new ModbusNode();
private ModbusGroup modbusGroup = new ModbusGroup();
private void btnInsert_Click(object sender, EventArgs e)
{
//using (MyDbContext dbContext = new MyDbContext())
//{
// this.nodeClass = configRoot.GetSection("NodeClass").Get<NodeClass>();
// this.modbusNode = configRoot.GetSection("NodeClass:ModbusNode").Get<ModbusNode>();
// this.modbusGroup = configRoot.GetSection("NodeClass:ModbusNode:ModbusGroup").Get<ModbusGroup>();
// dbContext.NodeClasses.AddAsync(this.nodeClass);
// dbContext.ModbusNodes.AddAsync(this.modbusNode);
// dbContext.ModbusGroups.AddAsync(this.modbusGroup);
// List<Variable> variables = new List<Variable>();
// for (int i = 0; i < int.Parse(CommonMethods.VarNum); i++)
// {
// Variable variable = configRoot.GetSection($"NodeClass:ModbusNode:ModbusGroup:Variable:{i}").Get<Variable>();
// variables.Add(variable);
// }
// dbContext.Variables.AddRangeAsync(variables);
// dbContext.SaveChangesAsync();
//}
}
private void btnIn_Click(object sender, EventArgs e)
{
//List<ActualData> list = new List<ActualData>();
ModelsResponsitory db = new ModelsResponsitory();
this.Dgv.DataSource= db.GetActualData();
}
}
}
插入数据库
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class InsertDataSQLite
{
System.Timers.Timer t;
int count = 0;
public InsertDataSQLite(int Interval)
{
t = new System.Timers.Timer(Interval);
t.Elapsed += T_Elapsed;
t.AutoReset = true;
t.Enabled = true;
t.Start();
count = CommonMethods.CacheCount; //默认为600
}
private void T_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (CommonMethods.IsConnected)
{
InsertActualData();
}
}
private void InsertActualData()
{
if (CommonMethods.CurrentPLCValue != null && CommonMethods.CurrentPLCValue.Count > 0)
{
List<ActualData> actualDataArray = new List<ActualData>();
//List<ReportData> reportDataArray = new List<ReportData>();
DateTime dt = DateTime.Now;
foreach (var item in CommonMethods.AllVarList) //FileVarModbusList归档集合
{
string varName = item.Name;//modbus 点表中的名称
string description = item.Description; //注释
double value = 0;
if (!CommonMethods.CurrentPLCValue.ContainsKey(varName))
{
value = 0;
}
else
{
value = double.Parse(item.Value);
//value = Convert.ToDouble(CommonMethods.CurrentPLCValue[varName]);
}
if (actualDataArray.Count <= 1000)
{
actualDataArray.Add(new ActualData()
{
InsertTime = dt,
Name = varName,
Value = value.ToString("f2"),
Description = description
});
}
else
{
actualDataArray.RemoveAt(0);
}
}
var db = new ModelsResponsitory();
db.AddActualData(actualDataArray);
}
}
}
}
通用类
using Microsoft.EntityFrameworkCore.Query;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class CommonMethods
{
public static Dictionary<string, object> CurrentPLCValue = new Dictionary<string, object>();
//归档变量集合
public static List<Variable> ArchiveVarList = new List<Variable>();
//所有
public static List<Variable> AllVarList = new List<Variable>();
/// <summary>
/// 键值对,键是变量名称,值是其对应的变量实体对象 用来写数据
/// </summary>
public static Dictionary<string, Variable> CurrentPLCVariable = new Dictionary<string, Variable>();
/// <summary>
/// 变量名称和变量地址的键值对
/// </summary>
public static Dictionary<string, string> CurrentPLCNote = new Dictionary<string, string>();
public static bool IsConnected = false;
public static int CacheCount = 600;//10分钟, 每秒一条
public static IIncludableQueryable<NodeClass, IEnumerable<Variable>> ModbusTCPList;
public static int ErrorTimes = 0;
public static bool FirstConnect = true;
public static string Ip;
public static string Port;
public static string VarNum;
}
}
EFcore的配置
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Sqlite;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
namespace EF6Demon
{
public class MyDbContext:DbContext
{
public DbSet<ActualData> ActualDatas { get; set; } //API中为复数, 而不是数据库表
public DbSet<NodeClass> NodeClasses { get; set; }
public DbSet<ModbusNode> ModbusNodes { get; set; }
public DbSet<ModbusGroup> ModbusGroups { get; set; }
public DbSet<Variable> Variables { get; set; }
public DbSet<SysAdmin> SysAdmins { get; set; }
private ConfigurationBuilder cfgBuilder = new ConfigurationBuilder();
//private IConfiguration configuration;
//private string connString;
public MyDbContext()
{
//configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("Ipcfg.json").Build();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
cfgBuilder.AddJsonFile("VariableNode.json", optional: true, reloadOnChange: true);
IConfigurationRoot configRoot = cfgBuilder.Build();
string connString = configRoot.GetSection("ConnectionStrings:SqliteConnectionString").Value;
optionsBuilder.UseSqlite(connString);
//configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("Ipcfg.json").Build();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//ConfigurationBuilder cfg1 = new ConfigurationBuilder();
//cfg1.AddJsonFile("VariableNode.json", optional: true, reloadOnChange: true);
//IConfigurationRoot configRoot = cfg1.Build();
//string varNum = configRoot.GetSection("NodeClass:ModbusNode:VarNum").Value;
//IList<Variable> iniVariableList = new List<Variable>();
//for (int i = 0; i < int.Parse(varNum); i++)
//{
// Variable variable = configRoot.GetSection($"NodeClass:ModbusNode:ModbusGroup:Variable:{i}").Get<Variable>();
// iniVariableList.Add(variable);
//}
var iniActualData = File.ReadAllText(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"/Database/Variable.json");
IList<ActualData> iniActualList = JsonConvert.DeserializeObject<IList<ActualData>>(iniActualData);
//modelBuilder.Entity<Variable>().HasData(iniVariableList);
modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
}
}
}
//VS终端下
// 视图-其他窗口-程序包控制台
//选择默认项目
//add-migration initialMigration //创建数据迁移
//add-migration initialMigration1 //创建数据迁移
// update-database
//Remove-migration 删除最后一次脚本
//Script-Migration 显示迁移的sql脚本
//DBfirst
// Scaffold-DbContext "server=192.168.207.107; database=Demon1; uid=root; pwd=123456" Pomelo.EntityFrameworkCore.MySql
//根据已有数据库创建数据模型。在 NuGet 的程序包管理(Package Manager)控制台中(PowerShell)执行命令:
//Scaffold-DbContext "server=数据库服务器;uid=数据库用户名;pwd=数据库密码;database=数据库名;" Pomelo.EntityFrameworkCore.MySql -OutputDir Data -Force
//.Net Core CLi:dotnet ef dbcontext scaffold "server=数据库服务器;uid=数据库用户名;pwd=数据库密码;database=数据库名;" Pomelo.EntityFrameworkCore.MySql -o Data -f
//CMD 命令下 安装EF工具:
//dotnet tool install --global dotnet-ef
//数据迁移:
//dotnet ef migrations add DataSeeding
//数据更新:
//dotnet ef database update
/*
* cmd命令:
Mysql数据库:
docker run --name mysqltest -p 3306:3306 -v /usr/local/mysql/data:/var/lib/mysql -v /usr/local/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql
dotnet ef migrations add MySQLInit
dotnet ef database update
dotnet ef database update MySQLUpdate3 回滚 对应版本
*/
模型:
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class Variable
{
public long Id { get; set; }
public string Number { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Type { get; set; }
public string VarAddress { get; set; }
public string Scale { get; set; }
public string Offset { get; set; }
public string Start { get; set; }
public string AccessProperty { get; set; }
public string AlarmEnable { get; set; }
public string ArchiveEnable { get; set; }
public string SetLimitEnable { get; set; }
public string AlarmType { get; set; }
public string DiscreteAlarmType { get; set; }
public string DiscreteAlarmPriority { get; set; }
public string DiscreteAlarmNote { get; set; }
public string LoLoAlarmEnable { get; set; }
public string LoLoAlarmValue { get; set; }
public string LoLoAlarmPriority { get; set; }
public string LoLoAlarmNote { get; set; }
public string LowAlarmEnable { get; set; }
public string LowAlarmValue { get; set; }
public string LowAlarmPriority { get; set; }
public string LowAlarmNote { get; set; }
public string HighAlarmEnable { get; set; }
public string HighAlarmValue { get; set; }
public string HighAlarmPriority { get; set; }
public string HighAlarmNote { get; set; }
public string HiHiAlarmEnable { get; set; }
public string HiHiAlarmValue { get; set; }
public string HiHiAlarmPriority { get; set; }
public string HiHiAlarmNote { get; set; }
public string ArchivePeriod { get; set; }
public string SetLimitMax { get; set; }
public string SetLimitMin { get; set; }
public string VarType { get; set; }
public string StoreType { get; set; }
public string InsertTime { get; set; }
public string Value { get; set; }
public long ModbusGroupId { get; set; }
public ModbusGroup ModbusGroup { get; set; }
}
}
using System.Collections.Generic;
namespace EF6Demon
{
public class ModbusGroup
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Type { get; set; }
public string StoreArea { get; set; }
public string Length { get; set; }
public string Start { get; set; }
public string SlaveID { get; set; }
public string IsActive { get; set; }
public long ModbusNodeId { get; set; }
public ModbusNode ModbusNode { get; set; }
public List<Variable> Variables { get; set; } = new List<Variable>();
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class ModbusNode
{
public ModbusNode()
{
}
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ModbusType { get; set; }
public string ConnectTimeOut { get; set; }
public string CreateTime { get; set; }
public string ReConnectTime { get; set; }
public string IsActive { get; set; }
public string MaxErrorTimes { get; set; }
public string KeyWay { get; set; }
public string UseAlarmCheck { get; set; }
public string ServerURL { get; set; }
public string Port { get; set; }
public string DataFormat { get; set; }
public string VarNum { get; set; }
public long NodeClassId { get; set; }
public List<ModbusGroup> ModbusGroups { get; set; } = new List<ModbusGroup>();
public NodeClass NodeClass { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class NodeClass
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<ModbusNode> ModbusNodes { get; set; } = new List<ModbusNode>();
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class ActualData
{
public long Id { get; set; }
public string Description { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public DateTime InsertTime { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF6Demon
{
public class SysAdmin
{
public long Id { get; set; }
public string LoginName { get; set; }
public string Pwd { get; set; }
public string HandCtrl { get; set; }
public string AutoCtrl { get; set; }
public string SysSet { get; set; }
public string SysLog { get; set; }
public string Report { get; set; }
public string Trend { get; set; }
public string UserManage { get; set; }
}
}
模型配置:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
internal class NodeClassConfig : IEntityTypeConfiguration<NodeClass>
{
public void Configure(EntityTypeBuilder<NodeClass> builder)
{
builder.ToTable("NodeClass");
builder.HasKey(a => a.Id);
builder.Property(a => a.Description).HasMaxLength(100);
builder.HasMany<ModbusNode>(n=>n.ModbusNodes).WithOne(m=> m.NodeClass);
}
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class ModbusNodeConfig : IEntityTypeConfiguration<ModbusNode>
{
public void Configure(EntityTypeBuilder<ModbusNode> builder)
{
builder.ToTable("ModbusNode");
builder.HasKey(a => a.Id);
builder.Property(a => a.Description).HasMaxLength(100);
builder.HasOne<NodeClass>(m => m.NodeClass)
.WithMany(n => n.ModbusNodes)
.HasForeignKey(c => c.NodeClassId);
}
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class ModbusGroupConfig : IEntityTypeConfiguration<ModbusGroup>
{
public void Configure(EntityTypeBuilder<ModbusGroup> builder)
{
builder.ToTable("ModbusGroup");
builder.HasKey(a => a.Id);
builder.Property(a => a.Description).HasMaxLength(100);
builder.HasOne<ModbusNode>(c => c.ModbusNode)
.WithMany(a => a.ModbusGroups)
.HasForeignKey(c => c.ModbusNodeId);
}
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class VariableConfig : IEntityTypeConfiguration<Variable>
{
public void Configure(EntityTypeBuilder<Variable> builder)
{
builder.ToTable("Variable");
builder.HasKey(v => v.Id);
builder.Property(v => v.Description).HasMaxLength(100);
builder.HasOne<ModbusGroup>(v => v.ModbusGroup).WithMany(m=>m.Variables).HasForeignKey(v=>v.ModbusGroupId);
}
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public class ActualDataConfig : IEntityTypeConfiguration<ActualData>
{
public void Configure(EntityTypeBuilder<ActualData> builder)
{
builder.ToTable("ActualData");
builder.HasKey(a => a.Id);
builder.Property(a => a.Description).HasMaxLength(100);
}
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EF6Demon
{
public class SysAdminConfig : IEntityTypeConfiguration<SysAdmin>
{
public void Configure(EntityTypeBuilder<SysAdmin> builder)
{
builder.ToTable("SysAdmins");
builder.HasKey(a => a.Id);
}
}
}
通过外键, 建立各设备组之间的关系,生成服务类
using Microsoft.EntityFrameworkCore.Query;
using System;
using System.Collections.Generic;
using System.Text;
namespace EF6Demon
{
public interface IProvider
{
List<ActualData> GetActualData();
void AddActualData(List<ActualData> actualData);
IIncludableQueryable<NodeClass, IEnumerable<Variable>> GetAllVariable();
}
}
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EF6Demon
{
public class ModelsResponsitory : IProvider
{
private MyDbContext db = new MyDbContext();
public MyDbContext Db
{
get { return db; }
set { db = value; }
}
public void AddActualData(List<ActualData> actualData)
{
db.ActualDatas.AddRangeAsync(actualData);
db.SaveChangesAsync();
}
public List<ActualData> GetActualData()
{
//IQueryable<ActualData> actualData = db.ActualDatas.Where(a=>a.Id>10);
//return actualData;
IEnumerable<ActualData> actualData1 = db.ActualDatas;
//IEnumerable<TSource> IOrderedEnumerable<TSource> OrderByDescending 全部取出,在内存中比较Where(a => a.Id > 10)
actualData1.Where(a => a.Id > 10).OrderByDescending(i => i.Id).Take(20);
//IQueryable<TSource> Where IOrderedQueryable<TSource> OrderByDescending, 给服务器发sql语句 Where(a => a.Id > 10)
//加上toList 把数据全部取回本地, 不占用带宽
IQueryable<ActualData> actualData =db.ActualDatas;
return actualData.Where(a => a.Id > 10).OrderByDescending(i => i.Id).Take(20).ToList();
}
public IIncludableQueryable<NodeClass, IEnumerable<Variable>> GetAllVariable()
{
return db.NodeClasses.
Include(n => n.ModbusNodes.Where(nodes => nodes.NodeClassId == 1))
.ThenInclude(m => m.ModbusGroups.Where(groups => groups.ModbusNodeId == 1))
.ThenInclude(gp => gp.Variables.Where(v => v.ModbusGroupId == 1));
}
}
}
本地配置文件:
{
"ConnectionStrings": {
"SqliteConnectionString": "Data Source=E:\\Csharp\\EF6Demon\\EF6Demon\\bin\\Debug\\net6.0-windows\\Database\\DbSqlite.db",
"MySQLConnectionString": "server=192.168.85.102; database=OneToMany; uid=root; pwd=123456;"
},
"NodeClass": {
"Id": 1,
"Name": "ModbusClent",
"Description": "Modbus相关客户端",
"ModbusNode": {
"Id": 1,
"NodeClassId": 1,
"Name": "ModbusTCPClient",
"Description": "1#ZG上位机测试",
"ModbusType": "2000",
"ConnectTimeOut": "2000",
"CreateTime": "0",
"ReConnectTime": "5000",
"IsActive": "True",
"MaxErrorTimes": "1",
"KeyWay": "VarName",
"UseAlarmCheck": "True",
"ServerURL": "127.0.0.1",
"Port": "502",
"DataFormat": "ABCD",
"VarNum": "6",
"ModbusGroup": {
"Id": 1,
"Name": "保持寄存器长度为寄存器个数",
"Description": "40001-40010",
"Type": "ModbusTCP",
"StoreArea": "40000",
"Length": "10",
"Start": "0",
"SlaveID": "1",
"IsActive": "true",
"ModbusNodeId": 1,
"Variable": [
{
"Id": 1,
"Number": "1",
"Name": "Float1",
"Description": "40001-40002",
"Type": "ModbusTCP",
"VarAddress": 0,
"Scale": "1",
"Offset": "0",
"Start": "0",
"AccessProperty": "读写",
"AlarmEnable": "True",
"ArchiveEnable": "True",
"SetLimitEnable": "True",
"AlarmType": "True",
"DiscreteAlarmType": "False",
"DiscreteAlarmPriority": "0",
"DiscreteAlarmNote": "null",
"LoLoAlarmEnable": "True",
"LoLoAlarmValue": "0",
"LoLoAlarmPriority": "0",
"LoLoAlarmNote": "40001-40002低低报警",
"LowAlarmEnable": "True",
"LowAlarmValue": "20",
"LowAlarmPriority": "0",
"LowAlarmNote": "40001-40002低报警",
"HighAlarmEnable": "True",
"HighAlarmValue": "80",
"HighAlarmPriority": "0",
"HighAlarmNote": "40001-40002高报警",
"HiHiAlarmEnable": "True",
"HiHiAlarmValue": "100",
"HiHiAlarmPriority": "0",
"HiHiAlarmNote": "40001-40002高高报警",
"ArchivePeriod": "80",
"SetLimitMax": "100",
"SetLimitMin": "0",
"VarType": "Float",
"StoreType": "03 Holding Register(4x)",
"InsertTime": "0",
"Value": "0",
"ModbusGroupId": 1
},
{
"Id": 2,
"Number": "2",
"Name": "Float2",
"Description": "40003-40004",
"Type": "ModbusTCP",
"VarAddress": 2,
"Scale": "1",
"Offset": "0",
"Start": "0",
"AccessProperty": "读写",
"AlarmEnable": "True",
"ArchiveEnable": "True",
"SetLimitEnable": "True",
"AlarmType": "True",
"DiscreteAlarmType": "False",
"DiscreteAlarmPriority": "0",
"DiscreteAlarmNote": "null",
"LoLoAlarmEnable": "True",
"LoLoAlarmValue": "0",
"LoLoAlarmPriority": "0",
"LoLoAlarmNote": "40003-40004低低报警",
"LowAlarmEnable": "True",
"LowAlarmValue": "20",
"LowAlarmPriority": "0",
"LowAlarmNote": "40003-40004低报警",
"HighAlarmEnable": "True",
"HighAlarmValue": "80",
"HighAlarmPriority": "0",
"HighAlarmNote": "40003-40004高报警",
"HiHiAlarmEnable": "True",
"HiHiAlarmValue": "100",
"HiHiAlarmPriority": "0",
"HiHiAlarmNote": "40003-40004高高报警",
"ArchivePeriod": "80",
"SetLimitMax": "100",
"SetLimitMin": "0",
"VarType": "Float",
"StoreType": "03 Holding Register(4x)",
"InsertTime": "0",
"Value": "0",
"ModbusGroupId": 1
},
{
"Id": 3,
"Number": "3",
"Name": "Float3",
"Description": "40005-40006",
"Type": "ModbusTCP",
"VarAddress": 4,
"Scale": "1",
"Offset": "0",
"Start": "0",
"AccessProperty": "读写",
"AlarmEnable": "True",
"ArchiveEnable": "True",
"SetLimitEnable": "True",
"AlarmType": "True",
"DiscreteAlarmType": "False",
"DiscreteAlarmPriority": "0",
"DiscreteAlarmNote": "null",
"LoLoAlarmEnable": "True",
"LoLoAlarmValue": "0",
"LoLoAlarmPriority": "0",
"LoLoAlarmNote": "40005-40006低低报警",
"LowAlarmEnable": "True",
"LowAlarmValue": "20",
"LowAlarmPriority": "0",
"LowAlarmNote": "40005-40006低报警",
"HighAlarmEnable": "True",
"HighAlarmValue": "80",
"HighAlarmPriority": "0",
"HighAlarmNote": "40005-40006高报警",
"HiHiAlarmEnable": "True",
"HiHiAlarmValue": "100",
"HiHiAlarmPriority": "0",
"HiHiAlarmNote": "40005-40006高高报警",
"ArchivePeriod": "80",
"SetLimitMax": "100",
"SetLimitMin": "0",
"VarType": "Float",
"StoreType": "03 Holding Register(4x)",
"InsertTime": "0",
"Value": "0",
"ModbusGroupId": 1
},
{
"Id": 4,
"Number": "4",
"Name": "Float4",
"Description": "40007-40008",
"Type": "ModbusTCP",
"VarAddress": 6,
"Scale": "1",
"Offset": "0",
"Start": "0",
"AccessProperty": "读写",
"AlarmEnable": "True",
"ArchiveEnable": "True",
"SetLimitEnable": "True",
"AlarmType": "True",
"DiscreteAlarmType": "False",
"DiscreteAlarmPriority": "0",
"DiscreteAlarmNote": "null",
"LoLoAlarmEnable": "True",
"LoLoAlarmValue": "0",
"LoLoAlarmPriority": "0",
"LoLoAlarmNote": "40003-40004低低报警",
"LowAlarmEnable": "True",
"LowAlarmValue": "20",
"LowAlarmPriority": "0",
"LowAlarmNote": "40003-40004低报警",
"HighAlarmEnable": "True",
"HighAlarmValue": "80",
"HighAlarmPriority": "0",
"HighAlarmNote": "40003-40004高报警",
"HiHiAlarmEnable": "True",
"HiHiAlarmValue": "100",
"HiHiAlarmPriority": "0",
"HiHiAlarmNote": "40003-40004高高报警",
"ArchivePeriod": "80",
"SetLimitMax": "100",
"SetLimitMin": "0",
"VarType": "Float",
"StoreType": "03 Holding Register(4x)",
"InsertTime": "0",
"Value": "0",
"ModbusGroupId": 1
},
{
"Id": 5,
"Number": "5",
"Name": "Ushort1",
"Description": "40009",
"Type": "ModbusTCP",
"VarAddress": 8,
"Scale": "1",
"Offset": "0",
"Start": "0",
"AccessProperty": "读写",
"AlarmEnable": "True",
"ArchiveEnable": "True",
"SetLimitEnable": "True",
"AlarmType": "True",
"DiscreteAlarmType": "False",
"DiscreteAlarmPriority": "0",
"DiscreteAlarmNote": "null",
"LoLoAlarmEnable": "True",
"LoLoAlarmValue": "0",
"LoLoAlarmPriority": "0",
"LoLoAlarmNote": "40009低低报警",
"LowAlarmEnable": "True",
"LowAlarmValue": "20",
"LowAlarmPriority": "0",
"LowAlarmNote": "40009低报警",
"HighAlarmEnable": "True",
"HighAlarmValue": "80",
"HighAlarmPriority": "0",
"HighAlarmNote": "40009高报警",
"HiHiAlarmEnable": "True",
"HiHiAlarmValue": "100",
"HiHiAlarmPriority": "0",
"HiHiAlarmNote": "40009高高报警",
"ArchivePeriod": "80",
"SetLimitMax": "100",
"SetLimitMin": "0",
"VarType": "UShort",
"StoreType": "03 Holding Register(4x)",
"InsertTime": "0",
"Value": "0",
"ModbusGroupId": 1
},
{
"Id": 6,
"Number": "6",
"Name": "Ushort2",
"Description": "40010",
"Type": "ModbusTCP",
"VarAddress": 9,
"Scale": "1",
"Offset": "0",
"Start": "0",
"AccessProperty": "读写",
"AlarmEnable": "True",
"ArchiveEnable": "True",
"SetLimitEnable": "True",
"AlarmType": "True",
"DiscreteAlarmType": "False",
"DiscreteAlarmPriority": "0",
"DiscreteAlarmNote": "null",
"LoLoAlarmEnable": "True",
"LoLoAlarmValue": "0",
"LoLoAlarmPriority": "0",
"LoLoAlarmNote": "40009低低报警",
"LowAlarmEnable": "True",
"LowAlarmValue": "20",
"LowAlarmPriority": "0",
"LowAlarmNote": "40009低报警",
"HighAlarmEnable": "True",
"HighAlarmValue": "80",
"HighAlarmPriority": "0",
"HighAlarmNote": "40009高报警",
"HiHiAlarmEnable": "True",
"HiHiAlarmValue": "100",
"HiHiAlarmPriority": "0",
"HiHiAlarmNote": "40009高高报警",
"ArchivePeriod": "80",
"SetLimitMax": "100",
"SetLimitMin": "0",
"VarType": "UShort",
"StoreType": "03 Holding Register(4x)",
"InsertTime": "0",
"Value": "0",
"ModbusGroupId": 1
}
]
}
}
}
}
更多推荐
已为社区贡献2条内容
所有评论(0)