n 層アーキテクチャを使用する古い asp.net アプリケーションに新しい機能を追加しています。基本的な例は次のように与えることができます
物体
public class Test
{
public int ID{get;set;}
public int name{get;set;}
}
データ アクセス層
public static List<Test> GetTests()
{
List<Test> list = new List<Test>();
try
{
//codes
SqlDataReader dr = com.ExecuteReader();
while(dr.Read())
list.Add(FillTestRecord(dr))
//codes
}
catch{}
return list;
}
private static Test FillTestRecord(IDataRecord dr)
{
Test test = new Test();
try{test.ID = Convert.ToInt32(dr["ID"]);}
catch{}
try{test.Name = Convert.ToInt32(dr["Name"]);}
catch{}
return test;
}
開発では、オブジェクト クラスに新しいフィールドを追加する必要があり、再利用性のために、オブジェクトの種類ごとに Fill*Record メソッドを 1 つだけ使用します。このメソッドは、IDataRecord にオブジェクトのすべての列が含まれていない可能性がある他の多くの DAL メソッドから呼び出すことができます。したがって、すべてのプロパティに個別に try-catch ブロックを配置します。これにより、IDataRecord で使用可能なすべての列が適切に解析されます。
私の質問は、それを行うより良い方法はありますか? また、このタイプのアーキテクチャでのベスト プラクティスは何ですか?
アップデート
David LとAnupのコメント/回答を読んだ後、Extension Methodを使用して別の方法を試しました。方法は次のとおりです。
public static bool TryGetOrdinal(this IDataRecord dr, string column, out int ordinal)
{
try
{
ordinal = dr.GetOrdinal(column);
}
catch(Exception ex)
{
ordinal = -1; //Just setting a value that GetOrdinal doesn't return
return false;
}
return true;
}
したがって、FillTestRecord
メソッドは次のようになります
private static Test FillTestRecord(IDataRecord dr)
{
Test test = new Test();
int ordinal = default(int);
if(dr.TryGetOrdinal("ID",out ordinal))
test.ID = Convert.ToInt32(dr.GetValue(ordinal));
if(dr.TryGetOrdinal("Name",out ordinal))
test.Name = Convert.ToString(dr.GetValue(ordinal));
return test;
}
これに関する提案は大歓迎です。
更新 03-02-2016
デバッグ中に、提供された列名try-catch
が. そこで、 の列名を取得してに置き換える新しいメソッドを作成しました。GetOrdinal
DataRecord
DataReader
GetOrdinal
Array.IndexOf
public static bool TryGetOrdinal(this IDataRecord dr, string[] columnNames, string column, out int ordinal)
{
ordinal = Array.IndexOf(columnNames, column);
return ordinal >= 0;
}
そして私FillTestRecord
は-
private static Test FillTestRecord(IDataRecord dr, string[] columnNames)
{
Test test = new Test();
int ordinal = default(int);
if(dr.TryGetOrdinal(columnNames, "id",out ordinal))
test.ID = Convert.ToInt32(dr.GetValue(ordinal));
if(dr.TryGetOrdinal(columnNames, "name",out ordinal))
test.Name = Convert.ToString(dr.GetValue(ordinal));
return test;
}
列名は次のように Fill メソッドに渡されます -
using (var dr = com.ExecuteReader())
{
string[] colNames = dr.GetColumnNames();
while (dr.Read())
list.Add(FillTestRecord(dr, colNames));
}
「GetColumnNames」は新しい拡張メソッドです -
public static string[] GetColumnNames(this IDataReader dr)
{
string[] columnNames = new string[dr.FieldCount];
for (int i = 0; i < dr.FieldCount; i++)
{
columnNames[i] = dr.GetName(i).ToLower();
}
return columnNames;
}