我们在搭建数字孪生场景时候,通过FBX将Revit模型导入Unity后,往往需要在Unity中去执行例如,点选构件后会可视化的展示构件属性信息等操作,那么就需要通过Unity去读取Mysql数据库中的数据来实现。那么要先实现如何将Revit数据存储到Mysql数据库当中。
执行前,打开VS2022,点击引用,要先到包管理器中引用 MySql.Data.dll。具体 MySql.Data.dll 如何来,看我另一篇文章。(需要会一部分Revit二次开发知识)。
(二)BIM-Unity 搭建数字孪生-Unity 连接 MySQL-CSDN博客
先上测试代码:
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
namespace Revit2MySQL
{
[Transaction(TransactionMode.Manual)]
public class Class1 : IExternalCommand
{
private MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
server = "localhost";
database = "mydatabase";
uid = "root";
password = "admin123";
string connectionString = $"Server = {server};Database = {database};Uid = {uid};Pwd = {password};";
connection = new MySqlConnection(connectionString);
try
{
connection.Open();
var CMD = new MySqlCommand("SELECT ID FROM mytable WHERE user_name = '456'", connection);
var result = CMD.ExecuteScalar();
if (result != null)
{
int id = Convert.ToInt32(result);
MessageBox.Show("找到 ID:" + id);
}
else
{
MessageBox.Show("未找到记录");
}
}
catch (MySqlException ex)
{
TaskDialog.Show("数据库错误", $"错误代码:{ex.Number}\n{ex.Message}");
}
catch (Exception ex)
{
MessageBox.Show("Error connecting to MySQL server" + ex.Message);
}
return Result.Succeeded;
}
}
}
以下部分是MySQL Net的设置,具体解释看我另一篇文章。
(二)BIM-Unity 搭建数字孪生-Unity 连接 MySQL-CSDN博客
server = "localhost";
database = "mydatabase";
uid = "root";
password = "admin123";
官方有规定了在写连接语句时候要求用 Server Database Uid 和 Pwd。
所以在写的时候,最好就遵照一样的规则,规范化。
string connectionString = $"Server = {server};Database = {database};Uid = {uid};Pwd = {password};";
这部分很好理解,直接连接,然后 执行 增删改查命令进行测试。
connection.Open();
var CMD = new MySqlCommand("SELECT ID FROM mytable WHERE user_name = '456'", connection);
var result = CMD.ExecuteScalar();
此处用了 "SELECT ID FROM mytable WHERE user_name = '456'" 的SQL语句,意思是从 名称为 “mytable” 的表中查询一个 user_name = 456 的 ID 的值。
我的数据库的内容如下,按照语句,我最后拿到的值应该是 2 。
然后来看看执行效果,很明显,我已经连上并且拿到了我想要的值。
现正式应用一下,现想要从Revit模型中的园区环境模型中,提取环境监测仪的设备信息。
主要要通过过滤器过滤出所有的环境监测仪,然后拿到各个设备 Element 的 Id,UniqueId和 Name 。
先建立数据表,Mysql的数据表如下:
C#代码如下,weather_monitoring_deviceFilter() 方法实现元素过滤,weather_monitoring_deviceFilter() 实现数据库连接并存储。
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Events;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
namespace Revit2MySQL
{
[Transaction(TransactionMode.Manual)]
public class Class1 : IExternalCommand
{
UIDocument uIDocument;
Document document;
private MySqlConnection connection;
private string server;
private string database;
private string uid;
private string password;
private List<DeviceInfo> devicesList = new List<DeviceInfo>();
private string connectionString;
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
uIDocument = commandData.Application.ActiveUIDocument;
document = uIDocument.Document;
server = "localhost";
database = "buildingsurroundings";
uid = "root";
password = "admin123";
connectionString = $"Server = {server};Database = {database};Uid = {uid};Pwd = {password};";
weather_monitoring_deviceFilter(document);
StoreDeviceInfoToDatabase(devicesList);
return Result.Succeeded;
}
void weather_monitoring_deviceFilter(Document document)
{
FilteredElementCollector deviceFilter = new FilteredElementCollector(document);
IList<Element> weatherDevicesList = deviceFilter.OfCategory(BuiltInCategory.OST_GenericModel).OfClass(typeof(FamilyInstance)).ToElements();
foreach (var item in weatherDevicesList)
{
if (item.Name.Contains("园区健康环境监测仪"))
{
var deviceId = item.Id;
var deviceUId = item.UniqueId;
var deviceName = item.Name;
DeviceInfo deviceInfo = new DeviceInfo
{
DeviceUId = deviceUId.ToString(),
Id = int.Parse(deviceId.ToString()),
Name = deviceName
};
devicesList.Add(deviceInfo);
}
}
}
void StoreDeviceInfoToDatabase(List<DeviceInfo> devicesList)
{
try
{
using (connection = new MySqlConnection(connectionString))
{
connection.Open();
foreach (var item in devicesList)
{
string sqlCmd = "INSERT INTO weather_monitoring_device (Id, DeviceId, Name) VALUES (@Id, @DeviceId, @Name);";
using (MySqlCommand mySqlCommand = new MySqlCommand(sqlCmd, connection))
{
mySqlCommand.Parameters.AddWithValue("@Id", item.Id);
mySqlCommand.Parameters.AddWithValue("@DeviceId", item.DeviceUId);
mySqlCommand.Parameters.AddWithValue("@Name", item.Name);
// 关键步骤:执行命令
mySqlCommand.ExecuteNonQuery();
}
MessageBox.Show("已成功存储~");
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
最终执行结果如下,已成功存储: