このコードは無駄が多く、風変わりで奇妙に思えるので、リファクタリングしたいと思います。
public string getVersion()
{
try
{
string dynSQL = "SELECT * FROM invHeader";
DataSet workSites = dbconn.getDataSet(dynSQL);
//Go thru dataset and display the working files
//Only need one, although we'll be duplicating the version
//per each site as a check value during upgrades
//return workSites.Tables[0].Rows
foreach (DataRow row in workSites.Tables[0].Rows)
{
sVersion = row["ID"].ToString();
break;
}
}
catch (Exception ex)
{
Duckbill.ExceptionHandler(ex, "InvHeader.getVersion");
}
return sVersion;
} // getVersion
私はそれを次のように変更できると考えていました:
public string getVersion()
{
try
{
string dynSQL = "SELECT FIRST ID FROM invHeader"; // I also tried "SELECT 1 ID FROM invHeader"
DataSet workSites = dbconn.getDataSet(dynSQL);
return workSites.Tables[0].Rows[0]["ID"].ToString();
}
catch (Exception ex)
{
Platypus.ExceptionHandler(ex, "InvHeader.getVersion");
}
} // getVersion
...しかし、どちらのクエリも必要なものを返しませんでした(最初の行の ID の値)。それで、それを行うためのSQLは何ですか。
ところで、これはある種のスカラー呼び出しであることはわかっていますが、相互に依存するこれらの自家製の自己ロール メソッドでは、非常に多くのファンキーな Rube Goldbergesque が発生します。ただし、この小さなクリーンアップは、ブーツで震えることなく実行できるはずです.
アップデート
SQL Server CE クエリ アナライザーで「SELECT TOP 1 ID FROM invHeader」という答えを出す銃を飛ばしたと思います。結果は次のようになります。
FAILED: SELECT TOP 1 ID FROM invHeader
Error: x800...._E_ERRORSINCOMMAND
Native Error: (25501)
Description: There was an error parsing the query. [Token line number, Token line offset, Token in error,,]
Interface defining error: IID_ICommand
Paaram. 0:1
Param. 1: 8
Param. 2:0
Param. 3: TOP
Param. 4:
Param. 5:
これは非常に不可解に思えますが、私が理解していることの 1 つは、SQL Server CE クエリ アナライザが「面白くない」ということです。
更新 2
私は、この同類のさらにひどいコード臭を発見しました。メソッドの名前から、メソッドが値を返すと思わせるだけではありません (そうです、本当です)。ただし、それを行っている間、最初のレコードを単純に取得するために、潜在的に大きなテーブルからすべてのレコードを取得します (再び)。
これを書いた猫が、「SELECT *」の乱暴な使用法に対するメモ警告を受け取らなかった可能性は本当にありますか?
コード難読化コンテストに匿名で応募できますか?
public string getINVSite()
{
string siteStr = "";
string dSQL = "";
DataSet workSites;
dSQL = "SELECT * FROM inventory";
dbconn = DBConnection.GetInstance();
workSites = dbconn.getDataSet( dSQL );
#if true
// DataRow row = workSites.Tables[0].Rows[0];
siteStr = "1";
if (workSites.Tables.Count > 0)
{
if(workSites.Tables[0].Rows.Count>0)
siteStr = workSites.Tables[0].Rows[0]["ID"].ToString();
}
return( siteStr );
#else
//Go thru dataset and display the working files
foreach( DataRow row in workSites.Tables[0].Rows )
{
return( row["ID"].ToString() );
}
return( "" );
#endif
} // getINVSite
今、あなたは私が負担している重荷を知っています。哀れに思うなら、あなたが選んだ慈善団体に寄付してください。
更新 3
申し訳ありません。あなたの助けに感謝しますが、これはウサギの穴が多すぎます。元のコードはマッドハッターにふさわしいものですが、機能します。もっと臭い魚を揚げなければならないので、少なくとも今のところは置いておきます。私はこれを試しました:
public string getVersion()
{
string conStr = "Data Source = " + dbconn.filename;
MessageBox.Show(string.Format("conStr in InvHeader.getVersion() is {0}", conStr));//TODO: Remove after testing
try
{
using (SqlCeConnection connection = new SqlCeConnection(conStr))
{
connection.Open();
using (SqlCeCommand command = new SqlCeCommand("SELECT ID FROM invHeader", connection))
using (SqlCeDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
string s = reader.GetString(0);
MessageBox.Show(string.Format("version InvHeader.getVersion() is {0}", s));//TODO: Remove after testing
return s;// reader.GetString(0);
}
else
{
// no result
return null;
}
}
}
}
catch (Exception ex)
{
Pterodactyl.ExceptionHandler(ex, "InvHeader.getVersion");
return string.Empty;
}
}
...それでも例外が発生します。最初の MessageBox.Show() で接続文字列を見た後、2 番目の文字列が表示されません。