在Visio的二次開發中,當發布圖紙的時候,我們往往需要保存圖紙和圖紙的設備信息到數據庫,圖紙是將文件以二進制保存到數據庫中,設備信息是保存圖紙對應的Shape的各種自定義屬性。本文主要介紹如何保存圖紙背後的設備信息。
這裡圖紙的設備信息可以通過一個設備表如Device1來放置同一類型的設備信息,如負荷開關存放在Device1,架空線放在Device2等等,Device(n)是我們詳細放置某種類型設備的表,其結構如下
另外主要我們再新建一個表來管理那種類型的設備對應那個表即可。如下圖所示:
一旦建立了上表的關系,我們就知道那個類型的設備對應的表名是多少了。我們通過代碼
List<DeviceTableInfo> deviceTables = deviceTableDAL.GetDeviceTables();
就可以獲取到所有的設備類型表的信息了,這可以為我們下一步保存設備信息做准備。
為了獲取到某個設備類型對應的表信息,我們可以這樣拿到它的對應信息。
string deviceType = VisioUtility.GetShapeCellValue(shape, "設備類型");
DeviceTableInfo tableInfo = deviceTableDAL.GetTableNameByDevice(deviceTables, deviceType);
我們知道,圖紙有很多信息,我們遍歷圖紙設備的時候,可以通過遍歷其選區實現,如下所示
if (VisioUtility.HasShapeInWindow(visWindow))
{
visWindow.SelectAll();
foreach (Visio.Shape shape in visWindow.Selection)
{
}
visWindow.DeselectAll();
}
這樣,我們有表的信息,又有了圖紙設備遍歷的方法,那我們就可以根據這些信息,生成保存每個設備的SQL語句了,你說是麼?因為每個Shape有很多屬性信息,我們把屬性信息保存到數據庫就可以了啊。
說到這裡,我們需要注意一個問題,設備有很多屬性列表,數據庫也有很多字段屬性列表,我們需要以一個為准,作為Sql語句字段列表的標准,否則就會出現問題。由於取本地Shape的屬性雖然方便,但是由於其可能因為模具屬性變化可能和數據庫的字段列表不再一致,因此還是以數據庫字段列表為准比較妥當。
為了獲取某個表的字段列表信息,我們需要使用下面代碼(該代碼是我代碼生成工具的基本函數來的,呵呵)
private DataTable GetReaderSchema(string tableName)
{
DataTable schemaTable = null;
string sql = string.Format("select * from [{0}]", tableName);
Database db = DatabaseFactory.CreateDatabase();
using (DbConnection connnection = db.CreateConnection())
{
connnection.Open();
DbCommand dbCommand = db.GetSqlStringCommand(sql);
dbCommand.Connection = connnection;
using (IDataReader reader = dbCommand.ExecuteReader(CommandBehavior.KeyInfo | CommandBehavior.SchemaOnly))
{
schemaTable = reader.GetSchemaTable();
}
}
return schemaTable;
}
上面的函數是獲取表的Schema信息,通過獲取對應的信息,我們就知道一個表有那些字段了,下面的代碼是實現把字段信息寫到列表中。
DataTable schemaTable = GetReaderSchema(tableName);
List<string> nameList = new List<string>();
foreach (DataRow dr in schemaTable.Rows)
{
nameList.Add(dr["ColumnName"].ToString());
}
然後,通過遍歷字段列表,我們就知道Insert語句的字段列表了,為了找到對應某個字段的值,我們可以使用下面代碼實現獲取Shape屬性對應的值(有則拿出來,否則賦給NULL)
string value = VisioUtility.GetShapeCellValue(shape, column.ColumnName);
if(!string.IsNullOrEmpty(value))
{
sqlValues += string.Format("'{0}',", value);
}
else
{
sqlValues += "NULL,";
}
這樣我們就可以構造完成一個Shape的Insert語句了,其他的也就如此這般就OK啦。其實就是在剛才的遍歷函數中,生成每一條Sql語句,放到列表中,然後統一執行這些Sql語句就實現設備的保存工作了。