max*_*sam 0 c# linq reflection datatable
我有这样的数据表
Name| Value
----|------
NA | VA
NB | VB
NC | VC1
NC | VC2
ND | VD1
ND | VD2
Run Code Online (Sandbox Code Playgroud)
和这样的一个类
Class NVMapping {
List<string> NC { get; set; }
List<string> ND { get; set; }
string NA { get; set; }
string NB { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如何使用linq或其他方式将数据表传输到此类型?
我想我需要在这里强调一件事.这种映射在我的应用程序中将会很多.
不知怎的,我认为使用反射可以使这个函数是通用的,以处理所有这些有点映射.
所以,如果可能的话,我更喜欢使用泛型函数来实现这一点.
如果可能的话,将数据表转移到像上面转换的对象中更好.
谢谢 !
我可以建议编写一个使用反射的泛型方法.以下方法使用反射从DataTable中的DataRow(或类的List <>,DataTable中的每个DataRow中的一个)填充类的公共属性,其中ColumnName完全匹配类中公共属性的名称(case -敏感).如果DataTable具有与类中的属性不匹配的额外列,则会忽略它们.如果DataTable缺少与类属性匹配的列,则忽略该属性并保留该类型的默认值(因为它是属性).
public static IList<T> DatatableToClass<T>(DataTable Table) where T : class, new()
{
if (!Helper.IsValidDatatable(Table))
return new List<T>();
Type classType = typeof(T);
IList<PropertyInfo> propertyList = classType.GetProperties();
// Parameter class has no public properties.
if (propertyList.Count == 0)
return new List<T>();
List<string> columnNames = Table.Columns.Cast<DataColumn>().Select(column => column.ColumnName).ToList();
List<T> result = new List<T>();
try
{
foreach (DataRow row in Table.Rows)
{
T classObject = new T();
foreach (PropertyInfo property in propertyList)
{
if (property != null && property.CanWrite) // Make sure property isn't read only
{
if (columnNames.Contains(property.Name)) // If property is a column name
{
if (row[property.Name] != System.DBNull.Value) // Don't copy over DBNull
{
object propertyValue = System.Convert.ChangeType(
row[property.Name],
property.PropertyType
);
property.SetValue(classObject, propertyValue, null);
}
}
}
}
result.Add(classObject);
}
return result;
}
catch
{
return new List<T>();
}
}
如果你有兴趣走另一条路,并从类的公共属性中填写DataTable,我会在我的C#博客上更多地介绍它,CSharpProgramming.tips/Class-to declaredTable