@ user1553525の答えは素晴らしいですが、列名がプロパティ名と正確に一致しない場合は機能しません。
したがって、最初にカスタム属性を作成する必要があります。次に、逆シリアル化しようとしているクラスの属性を使用します。最後に、DataTable を逆シリアル化します。
カスタム属性
クラス内のプロパティに適用されるカスタム属性を作成します。Name
DataTable から正しい列を取得するために後で使用するプロパティを持つクラスを作成します。
[AttributeUsage(AttributeTargets.Property, Inherited = false)]
public class MySqlColName : Attribute
{
private string _name = "";
public string Name { get => _name; set => _name = value; }
public MySqlColName(string name)
{
_name = name;
}
}
逆シリアル化するクラス
[MySqlColName]
次に、入力するクラスで、作成したばかりの属性を使用して、クラスのプロパティにリンクする列名を宣言します。
ただし、プロパティ名がデータベース列と同じ場合、.ToList<>()
関数はプロパティ名から列の名前を想定するため、属性に列名を指定する必要はありません。
public class EventInfo
{
[MySqlColName("ID")]
public int EventID { get; set; }
//Notice there is no attribute on this property?
public string Name { get; set; }
[MySqlColName("State")]
public string State { get; set; }
[MySqlColName("Start_Date")]
public DateTime StartDate { get; set; }
[MySqlColName("End_Date")]
public DateTime EndDate { get; set; }
}
DataTable ToList 拡張メソッド
最後に、カスタム属性が提供されているかどうかを確認するチェックを追加して、@ user1553525の回答を変更します。そうである場合は、列の名前を提供された名前に設定します。それ以外の場合は、プロパティ名を使用します (try ブロック内のコードを参照)。
public static List<T> ToList<T>(this DataTable table) where T : class, new()
{
try
{
List<T> list = new List<T>();
foreach (var row in table.AsEnumerable())
{
T obj = new T();
foreach (var prop in obj.GetType().GetProperties())
{
try
{
//Set the column name to be the name of the property
string ColumnName = prop.Name;
//Get a list of all of the attributes on the property
object[] attrs = prop.GetCustomAttributes(true);
foreach (object attr in attrs)
{
//Check if there is a custom property name
if (attr is MySqlColName colName)
{
//If the custom column name is specified overwrite property name
if (!colName.Name.IsNullOrWhiteSpace())
ColumnName = colName.Name;
}
}
PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
//GET THE COLUMN NAME OFF THE ATTRIBUTE OR THE NAME OF THE PROPERTY
propertyInfo.SetValue(obj, Convert.ChangeType(row[ColumnName], propertyInfo.PropertyType), null);
}
catch
{
continue;
}
}
list.Add(obj);
}
return list;
}
catch
{
return null;
}
}//END METHOD
使用法
最後に、.ToList<>()
メソッドを呼び出して、シリアル化されたオブジェクトのリストを取得できます
List<EventInfo> CustomObjectList;
using (DataTable dtCustomer = GetDataTable("SELECT * FROM EventIndex"))
{
CustomObjectList = dtCustomer.ToList<EventInfo>();
}
サイドノート:私が使用したカスタムメソッドがいくつかあります
public static bool IsNullOrWhiteSpace(this string x)
{
return string.IsNullOrWhiteSpace(x);
}
public static DataTable GetDataTable(string Query)
{
MySqlConnection connection = new MySqlConnection("<Connection_String>");
try
{
DataTable data = new DataTable();
connection.Open();
using (MySqlCommand command = new MySqlCommand(Query, connection))
{
data.Load(command.ExecuteReader());
}
return data;
}
catch (Exception ex)
{
// handle exception here
Console.WriteLine(ex);
throw ex;
}
finally
{
connection.Close();
}
}