C#List to DataTable扩展方法未检索属性
我想将knomolijst类型的ObservableCollection转换为DataTable。我找到了它的扩展方法,但它没有检索我的属性 扩展方法:C#List to DataTable扩展方法未检索属性,c#,.net,generics,reflection,extension-methods,C#,.net,Generics,Reflection,Extension Methods,我想将knomolijst类型的ObservableCollection转换为DataTable。我找到了它的扩展方法,但它没有检索我的属性 扩展方法: public static class ListToDataTable { public static DataTable ToDataTable<T>(this IList<T> items) { DataTable dataTable = new Dat
public static class ListToDataTable
{
public static DataTable ToDataTable<T>(this IList<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
//Get all the properties
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo prop in Props)
{
//Defining type of data column gives proper data table
var type = (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType);
//Setting column names as Property names
dataTable.Columns.Add(prop.Name, type);
}
foreach (T item in items)
{
var values = new object[Props.Length];
for (int i = 0; i < Props.Length; i++)
{
//inserting property values to datatable rows
values[i] = Props[i].GetValue(item, null);
}
dataTable.Rows.Add(values);
}
//put a breakpoint here and check datatable
return dataTable;
}
}
这是它接收到的knomolijst类型:
public class KNMOLijst
{
public string VoorLetters { get; set; }
public string Voornaam { get; set; }
public string TussenVoegsel { get; set; }
public string Achternaam { get; set; }
public string Geslacht { get; set; }
public DateTime GeboorteDatum { get; set; }
public string InstrumentNaam { get; set; }
public KNMOLijst()
{
}
}
我确保这些财产是公开的
这是扩展方法接收的列表
generatedList.Add(new KNMOLijst()
{
VoorLetters = (string)(row["VoorLetters"]),
Voornaam = (string)(row["Voornaam"]),
TussenVoegsel = (string)(row["TussenVoegsel"]),
Achternaam = (string)row["Achternaam"],
Geslacht = (string)row["Geslacht"],
GeboorteDatum = (DateTime)row["GeboorteDatum"],
InstrumentNaam = (string)row["InstrumentNaam"]
});
调用ToDataTable方法的我的viewmodel
public class SecretarisViewModel : BaseViewModel
{
private readonly SecretarisBLL secretarisBll;
private ObservableCollection<object> generatedList;
public ObservableCollection<object> GeneratedList
{
get { return generatedList; }
set
{
generatedList = value;
NotifyPropertyChanged();
}
}
private DataTable generatiedDataTable;
public DataTable GeneratedDataTable
{
get => generatiedDataTable;
set
{
generatiedDataTable = value;
NotifyPropertyChanged();
}
}
public SecretarisViewModel()
{
secretarisBll = new SecretarisBLL();
GeneratedList = new ObservableCollection<object>();
generatiedDataTable = new DataTable();
}
public async Task GetKNMOList()
{
var dataset = await secretarisBll.GetKNMOList();
foreach (DataRow row in dataset.Tables[0].Rows)
{
generatedList.Add(new KNMOLijst()
{
VoorLetters = (string)(row["VoorLetters"]),
Voornaam = (string)(row["Voornaam"]),
TussenVoegsel = (string)(row["TussenVoegsel"]),
Achternaam = (string)row["Achternaam"],
Geslacht = (string)row["Geslacht"],
GeboorteDatum = (DateTime)row["GeboorteDatum"],
InstrumentNaam = (string)row["InstrumentNaam"]
});
}
GeneratedDataTable = generatedList.ToDataTable();
}
}
公共类SecretarisViewModel:BaseViewModel
{
私有只读SecretarisBLL SecretarisBLL;
私有可观察集合生成列表;
公共可观测集合生成列表
{
获取{return generatedList;}
设置
{
生成列表=值;
NotifyPropertyChanged();
}
}
私有数据表GeneratedDataTable;
公共数据表GeneratedDataTable
{
get=>generatiedDataTable;
设置
{
GeneratedDataable=值;
NotifyPropertyChanged();
}
}
公共秘书视图模型()
{
secretarisBll=新secretarisBll();
GeneratedList=新的ObservableCollection();
GenerateedDataTable=新数据表();
}
公共异步任务getknomolist()
{
var dataset=await secretarisBll.getknomlist();
foreach(数据集中的DataRow行。表[0]。行)
{
Add(新的knomolijst()
{
VoorLetters=(字符串)(第[“VoorLetters”]行),
Voornaam=(字符串)(行[“Voornaam”]),
TussenVoegsel=(字符串)(第[“TussenVoegsel”]行),
Achternaam=(字符串)行[“Achternaam”],
Geslacht=(字符串)行[“Geslacht”],
Geboortedatam=(日期时间)行[“Geboortedatam”],
InstrumentNaam=(字符串)行[“InstrumentNaam”]
});
}
GeneratedDataTable=generatedList.ToDataTable();
}
}
为什么它无法获取列表的属性
生成的列表是一个可观察的集合,
所以我假设如果我在其中添加一个新的knomolijst行,它会
是Knomolijst类型的吗
否,如果列表的类型为observateCollection
,则T
为System.Object
,它没有公共属性。因此,将其设置为一个可观察的集合
如果无法执行此操作,请修改方法以从第一项派生类型:
public static DataTable ToDataTable<T>(this IList<T> items)
{
Type type = items.FirstOrDefault()?.GetType();
if (type == null)
throw new InvalidOperationException("The properties are derived from the first item, so the list must not be empty");
DataTable dataTable = new DataTable(type.Name);
//Get all the properties
PropertyInfo[] Props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
// ...
}
公共静态数据表到数据表(此IList项)
{
类型类型=items.FirstOrDefault()?.GetType();
if(type==null)
抛出新的InvalidOperationException(“属性派生自第一项,因此列表不能为空”);
DataTable=新的DataTable(type.Name);
//获取所有属性
PropertyInfo[]Props=type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
// ...
}
顺便说一下,这种行为(在空列表上抛出
invalidooperationexception
)与执行相同操作的行为类似。它还需要使用反射来获取列。什么是T
——生成列表的类型是什么?如果它不是实现IList的东西,那么它不会起作用。到目前为止,您尝试了什么?列表的类型正确吗?代码对我有效。通过你的样本检查,有效。因此,我猜您的行
不包含这些值。您可以在调用ToDataTable方法的位置添加代码吗?@JeroenMostert生成的列表是一个ObservableCollection,因此我假设如果我将一个新的knomolijst行添加到其中,它将属于knomolijst类型?我尝试了这一点,但在调试过程中跳过了类型检查。这是类型到达该行时包含的内容:{Name=“knomolijst”FullName=“Gildenbondsharmonie.BO.Lists.knomolijst”}。但它仍然没有收到我的属性?@Brum:跳过了哪种类型检查?该部分:type type type=items.FirstOrDefault()?.GetType();如果(type==null)type=typeof(T);但是我将包括项目中内容的屏幕截图。@Brum:我已经用您的示例检查了该方法,并声明它为observetecollection
。在我更改之前,它不工作,因为System.Object
被用作类型,现在它工作了。你是我的人,是我的英雄!我没有注意到你有过一次机会,当我修改代码时,它起了作用。谢谢你的时间,我真的很感激!
public static DataTable ToDataTable<T>(this IList<T> items)
{
Type type = items.FirstOrDefault()?.GetType();
if (type == null)
throw new InvalidOperationException("The properties are derived from the first item, so the list must not be empty");
DataTable dataTable = new DataTable(type.Name);
//Get all the properties
PropertyInfo[] Props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
// ...
}