简体   繁体   English

如何转换 Object 包含 IList<class> 其中还包含 6 个属性 - 4 个字符串,1 个 IList<anotherclass> , 1 个 IList<string> 到数据表?</string></anotherclass></class>

[英]How to convert Object contains IList<class> which further contains 6 properties - 4 string, 1 IList<anotherclass>, 1 IList<string> to DataTable?

I am trying to convert my Object which have only 1 item (IList of class), this class contains 6 properties - 4 string, 1 IList of anotherClass and 1 IList of string.我正在尝试转换我的 Object ,它只有 1 个项目(类的 IList),这个 class 包含 6 个属性 - 4 个字符串,1 个 IList of anotherClass 和 1 个 IList of string。 I am using below generic method to convert:-我正在使用以下通用方法进行转换:-

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;
    }

At this point - dataTable.Rows.Add(values);此时 - dataTable.Rows.Add(values); I have the list values for 4 and 5 properties but when I add those to row, it shows text(type of property) in the row.我有 4 和 5 个属性的列表值,但是当我将它们添加到行时,它会在行中显示文本(属性类型)。 While I need each item of 4 and 5 properties to come in next Row.虽然我需要 4 和 5 个属性中的每一项才能进入下一行。 For Example:-例如:-

values[0] - "FirstString",
values[1] - "SecondString",
values[2] - "ThirdString",
values[3] - "FourthString",
values[4] - Count 2 - 100, 200 (IList<AnotherClass>()),
values [5] - Count 2 - "10W", "20W" (IList<string>)

I want below type of output:-我想要以下类型的 output:-

1String     | 2String      | 3String     | 4String      | Per | W  |
:-----------|:------------:|:-----------:|:------------:|:---:|---:|
FirstString | SecondString | ThirdString | FourthString | 100 | 10W|
FirstString | SecondString | ThirdString | FourthString | 200 | 20W|

While the output I am currently getting is:-虽然我目前得到的 output 是:-

1String     | 2String      | 3String     | 4String      | Per            | W                 |
:-----------|:------------:|:-----------:|:------------:|:--------------:|--------------:|
FirstString | SecondString | ThirdString | FourthString | typeofproperty | typeofproperty|

I just want my object's list to convert to DataTable.我只想将我的对象列表转换为 DataTable。

Below is the debugging result as per the solution given below:-以下是根据下面给出的解决方案的调试结果:- 在此处输入图像描述

@Dennis, Still getting type of property as value for list type property. @Dennis,仍然将属性类型作为列表类型属性的值。 在此处输入图像描述

Your code works fine for T which contains only scalar properties (that is, primitive types, strings, dates, etc).您的代码适用于仅包含标量属性(即原始类型、字符串、日期等)的T
When it deals with collection or nested object, it tries to store that object or collection in data table's row as is, so the result is not as you expected.当它处理集合或嵌套的 object 时,它会尝试将 object 或集合按原样存储在数据表的行中,因此结果与您预期的不一样。

To get the output you want, you need to flatten list items first.要获得您想要的 output,您需要先展平列表项。 Since T could be anything, flatten logic cannot be implemented in generic manner.由于T可以是任何东西,因此无法以通用方式实现展平逻辑。 But the caller can do this for you, since he knows everything about object structure.但是调用者可以为你做这件事,因为他对 object 结构了如指掌。

Having these types:有这些类型:

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; }
}

you can write this code:您可以编写以下代码:

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();

Result:结果:

在此处输入图像描述

As you can see, flatten logic inside SelectMany depends on what T is.如您所见, SelectMany中的展平逻辑取决于T是什么。 If there will be, say, 3 nested lists and Bar will contain public Boo { get; set; }例如,如果有 3 个嵌套列表,并且Bar将包含public Boo { get; set; } public Boo { get; set; } public Boo { get; set; } property, that logic will change to reflect new object structure. public Boo { get; set; }属性,该逻辑将改变以反映新的 object 结构。

PS I've modified ToDataTable definition a little to make it extension method for IEnumerable<T> : PS 我稍微修改了ToDataTable定义,使其成为IEnumerable<T>的扩展方法:

static class ConversionExtensions
{
    public static DataTable ToDataTable<T>(this IEnumerable<T> items)
    {
        // your code here
    }
}

如何转换 IList<object> 到字符串数组?<div id="text_translate"><h2> 如何将 IList 对象转换为字符串数组?</h2><p> 在使用电报机器人时,出现了一些困难。 我从谷歌表中得到一个IList&lt;object&gt;和一些信息。 我需要将此IList&lt;object&gt;转换为字符串数组。 我怎样才能做到这一点?</p><pre> static void ReadBudgetTypes() { var range = $"{settingsSheet}:B3;B". var request = service.Spreadsheets.Values,Get(SpreadsheetId; range). var response = request;Execute(). var values = response;Values. // here i get list of objects from google table if (values.= null &amp;&amp; values,Count &gt; 0) { foreach (var row in values) { Console;WriteLine("{0}". row[0]); } } else { Console.WriteLine("No data!"); } }</pre></div></object> - How can I convert IList<object> to string array?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 IList.Contains(string [])如何在C#中? - IList.Contains(string[]) how to in C#? 如何序列化IList <object> 串 - How to serialize IList<object> to string 使用LINQ,如何转换IList <IList<object> &gt;至IList <object> ? - Using LINQ, how to convert a IList<IList<object>> to IList<object>? Cast IList <string> 到IList <object> 在运行时失败 - Cast IList<string> to IList<object> fails at runtime 将包含IList的对象序列化为XML - Serialize to XML an object that contains IList 如何初始化IList <IList <string >>? - How can I initialize a IList<IList<string>>? 转换IList <int> 到IList <string> - cast IList<int> to IList<string> 如何转换 IList<object> 到字符串数组?<div id="text_translate"><h2> 如何将 IList 对象转换为字符串数组?</h2><p> 在使用电报机器人时,出现了一些困难。 我从谷歌表中得到一个IList&lt;object&gt;和一些信息。 我需要将此IList&lt;object&gt;转换为字符串数组。 我怎样才能做到这一点?</p><pre> static void ReadBudgetTypes() { var range = $"{settingsSheet}:B3;B". var request = service.Spreadsheets.Values,Get(SpreadsheetId; range). var response = request;Execute(). var values = response;Values. // here i get list of objects from google table if (values.= null &amp;&amp; values,Count &gt; 0) { foreach (var row in values) { Console;WriteLine("{0}". row[0]); } } else { Console.WriteLine("No data!"); } }</pre></div></object> - How can I convert IList<object> to string array? 是DataTable还是IList? 哪个更好? - DataTable or IList? Which is better? C#如何将具有IList的对象转换为IList <object> ? - C# How to convert an object with IList to IList<object>?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM