用户1553525的回答很好,但是如果列名与属性名不完全匹配,则不起作用。
因此,您首先需要创建一个自定义属性。然后在您要反序列化的类中使用该属性,最后将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; }
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
{
string ColumnName = prop.Name;
object[] attrs = prop.GetCustomAttributes(true);
foreach (object attr in attrs)
{
if (attr is MySqlColName colName)
{
if (!colName.Name.IsNullOrWhiteSpace())
ColumnName = colName.Name;
}
}
PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
propertyInfo.SetValue(obj, Convert.ChangeType(row[ColumnName], propertyInfo.PropertyType), null);
}
catch
{
continue;
}
}
list.Add(obj);
}
return list;
}
catch
{
return null;
}
}
使用
最后,我们可以调用.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)
{
Console.WriteLine(ex);
throw ex;
}
finally
{
connection.Close();
}
}
DataContext.ExecuteQuery
。 - mellamokb