在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語句就實作裝置的儲存工作了。