OracleCommand Visualizer for VS2010
5 |
前陣子開發系統時,常在抓OracleCommand的執行期錯誤,有時是SQL語法寫錯,有時是參數數目不符,有時則是參數值給錯... (列原因寫到自己都汗顏,寫程式明明就要心思細膩,我的心思... 應該粗如電線桿吧?)
雖然VS2010在偵錯階段提供了很強的物件檢視功能,能逐一檢視物件的每個屬性且能逐層展開,必要時還可用即時運算視窗下指令做進一步操作分析,但每次要逐一檢查OracleCommand.Parameters還是有些麻煩,心想,如果能一次列出CommandText及所有參數的型別跟內容就太好了。
之前知道Visual Studio可以自訂Visualizer(視覺化檢視),在網路上撈了一下,只找得到現成的SqlCommand Visualizer,似乎沒人寫好OracleCommand用的檢視器,所以... 捲起袖子自己寫一個吧! 也順便體驗一下Visualizer的開發。
我必須要說,MSDN文件整理得真好,照著逐步解說教學一步步做,三兩下就可寫好一個Visualizer,而且連如何測試偵錯的環節都已考慮好,貼心得不得了。
我做了一個WinForm,放了RichTextBox(原本還想加上Highlighter為語法上色,不過後來因發懶作罷)及GridView分別顯示CommandText及列出OracleParameter,程式不難寫,唯一要克服的是OracleCommand不支援Serializable,無法直接使用內建的VisualizerObjectSource讀取執行期的物件,因此我自訂了一個OracleCommandVisualizerObjectSource,把必要資訊取出轉成XML傳回:
public class OracleCommandVisualizerObjectSource : VisualizerObjectSource
{
public override void GetData(object target, Stream outgoingData)
{
XDocument xd = XDocument.Parse("<OracleCommand />");
OracleCommand cmd = target as OracleCommand;
xd.Root.Add(new XElement("CommandText", cmd == null ?
"null" : cmd.CommandText));
xd.Root.Add(new XElement("Parameters"));
XElement props = xd.Root.Element("Parameters");
if (cmd != null)
for (int i = 0; i < cmd.Parameters.Count; i++)
{
OracleParameter p = cmd.Parameters[i];
props.Add(
new XElement(
"Parameter",
new XAttribute("No", i.ToString()),
new XAttribute("Name", p.ParameterName),
new XAttribute("DbType", p.DbType.ToString()),
new XAttribute("OracleType", p.OracleType.ToString()),
p.Value == null ? "null" : p.Value.ToString()
));
}
base.GetData(xd.ToString(), outgoingData);
}
}
Visualizer在註冊時需特別宣告使用自訂VisualizerObjectSource:
using System.Data.OracleClient;
using System.Xml.Linq;
using Microsoft.VisualStudio.DebuggerVisualizers;
using OracleCommandVisualizer;
[assembly:System.Diagnostics.DebuggerVisualizer(
typeof(DebuggerVisualizer),
typeof(OracleCommandVisualizerObjectSource),
Target = typeof(OracleCommand),
Description = "Afa OracleCommand Viewer")]
namespace OracleCommandVisualizer
{
//REF: http://msdn.microsoft.com/en-us/library/ms164759.aspx
public class DebuggerVisualizer : DialogDebuggerVisualizer
{
protected override void Show(
IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider)
{
VisualizerForm vf = new VisualizerForm(
XDocument.Parse(objectProvider.GetObject().ToString()));
vf.ShowDialog();
}
public static void TestShowVisualizer(object objectToVisualize)
{
VisualizerDevelopmentHost host =
new VisualizerDevelopmentHost(
objectToVisualize, typeof(DebuggerVisualizer),
typeof(OracleCommandVisualizerObjectSource));
host.ShowVisualizer();
}
}
}
編譯完成後,將OracleCommandVisualizer.dll及OracleCommandVisualizer.pdb放到C:\Users\username\Documents\Visual Studio 2010\Visualizers,重新啟動VS2010,之後偵錯階段將滑鼠放到OracleCommand變數上,可按放大鏡圖示的向下箭頭叫出Visualizer:
如下圖所示,透過OracleCommand Viewer就可以一次看完CommandText跟所有OracleParameter內容,對於心思粗如電線桿的兩光程式工人來說,實在是一大恩物~~~
我已把專案放上CodePlex(http://oracmdvisualizer.codeplex.com/),有興趣下載玩玩或研究的同學可以過去看看。
Comments
# by Robin
多謝分享 ^_^
# by Ming
想問黑大..如果要改寫成SQL版本是否有需特別注意的地方呢!? 小弟不才....也想寫一個來使用!!
# by Jeffrey
to Ming, 改寫SQL版應該只要把Target = typeof(OracleCommand)換掉,另外做一個SqlCommandVisualizerObjectSource,在GetData()裡的處理對象換成SqlCommand/SqlParameter,顯示Form的部分可以共用(因為是吃XML,與Command型別無關),原則上改動幅度不大。另外,網路上可找到現成的SqlCommand Visualizer(http://www.codechimp.org/blog/post/SQL-Command-Visualizer-for-Visual-Studio-2005.aspx),你也可以參考看看。
# by Ming
感謝回覆,看來以我現在的程度要好好思考思考! 再不行我再求助公司大老! 若有成果,再行分享!!
# by Leo
感謝黑大~ 看完您的文章,我下午也用 VB.NET 做了一個 for VS2008 , Target Framework 2.0 的 Visualizer 來用 (工作環境需求)。大感謝~~ PS.MSDN真好用,看MSDN+黑大文章的說明,幾個小時就搞定了,感覺真好。 ^_^