C# 如何转换包含IList的对象<;类别>;它还包含6个属性-4个字符串,1个IList<;另一类>;,1 IList<;字符串>;到数据表?
我试图转换我的对象,它只有1个项(类的IList),这个类包含6个属性-4个字符串,1个其他类的IList和1个字符串的IList。 我正在使用以下通用方法进行转换:-C# 如何转换包含IList的对象<;类别>;它还包含6个属性-4个字符串,1个IList<;另一类>;,1 IList<;字符串>;到数据表?,c#,list,object,datatable,C#,List,Object,Datatable,我试图转换我的对象,它只有1个项(类的IList),这个类包含6个属性-4个字符串,1个其他类的IList和1个字符串的IList。 我正在使用以下通用方法进行转换:- public static DataTable ToDataTable<T>(IList<T> items) { DataTable dataTable = new DataTable(typeof(T).Name); //Get all the properti
public static DataTable ToDataTable<T>(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;
}
而我目前得到的输出是:-
1String | 2String | 3String | 4String | Per | W |
:-----------|:------------:|:-----------:|:------------:|:--------------:|--------------:|
FirstString | SecondString | ThirdString | FourthString | typeofproperty | typeofproperty|
我只想将对象的列表转换为DataTable
下面是根据下面给出的解决方案进行调试的结果:-
@Dennis,仍在获取属性类型作为列表类型属性的值。
对于只包含标量属性(即基元类型、字符串、日期等)的
T
,您的代码运行良好。当它处理集合或嵌套对象时,它会尝试按原样将该对象或集合存储在数据表的行中,因此结果并不像您所期望的那样 要获得所需的输出,首先需要展平列表项。 因为
T
可以是任何东西,所以扁平化逻辑不能以通用方式实现。但是调用者可以为您这样做,因为他知道关于对象结构的一切
具有以下类型:
class Foo
{
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
public string D { get; set; }
public IList<Bar> Bars { get; set; }
public IList<string> Strings { get; set; }
}
class Bar
{
public int A { get; set; }
}
您需要首先展平对象以使代码正常工作。用一般的方式来做这件事并不容易,因为t可以是任何东西,就像扁平化逻辑一样。如果
项
仅具有标量属性(我的意思是没有集合或其他嵌套对象)就可以转换为DTO,那么就容易多了。此方法的调用是toDataTable(IList)。我怎样才能把物体展平?打电话的人必须这样做。否则它就不会是微不足道的。另一个选项是对T
结构进行限制(例如,仅2个列表,列表长度相同),但在这种情况下,通用转换器没有意义。您好,示例中的item.Strings和stringValue是什么?item.bar.Zip(item.Strings,(bar,stringValue)=>new{BarA=bar.A,stringValue=stringValue})item.Strings
是Foo
类中的IList
属性stringValue
是item.Strings
的一项。我猜,你问的主要是关于Zip
方法-它只是由两个不同类型的序列组成第三个序列。从字面上说,是成对的序列(100,“10W”),(200,“20W”)。是的,这是可行的,但在定义了项之后,它不允许我调用ToDataTable()方法。让我定义类型。你知道吗?@EktaC,我不知道你修改过的代码是什么样子如果你可以发布或分享,请这样做。请看下面我提供的截图。
1String | 2String | 3String | 4String | Per | W |
:-----------|:------------:|:-----------:|:------------:|:--------------:|--------------:|
FirstString | SecondString | ThirdString | FourthString | typeofproperty | typeofproperty|
class Foo
{
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
public string D { get; set; }
public IList<Bar> Bars { get; set; }
public IList<string> Strings { get; set; }
}
class Bar
{
public int A { get; set; }
}
var items = new List<Foo>
{
new Foo
{
A = "FirstString",
B = "SecondString",
C = "ThirdString",
D = "FourthString",
Bars = new List<Bar>
{
new Bar { A = 100 },
new Bar { A = 200 }
},
Strings = new List<string>
{
"10W",
"20W"
}
}
};
var dataTable = items
.SelectMany(item => item.Bars.Zip(item.Strings, (bar, stringValue) => new
{
BarA = bar.A,
StringValue = stringValue
}),
(item, _) => new
{
item.A,
item.B,
item.C,
item.D,
_.BarA,
_.StringValue
})
.ToDataTable();
static class ConversionExtensions
{
public static DataTable ToDataTable<T>(this IEnumerable<T> items)
{
// your code here
}
}