为了账号安全,请及时绑定邮箱和手机立即绑定

将数据从嵌套的 c# 类导出到 csv 文件

将数据从嵌套的 c# 类导出到 csv 文件

C#
青春有我 2021-11-14 15:08:00
我有以下类可以使用,我想将内容导出/展平到 csv 文件。我曾尝试使用 SelectMany,但找不到从公司级别和带有 SalesArea、Node 和 EthernetArea 的底层级别为我的 csv 文件选择字段的方法。有人可以解释我需要做什么来实现这一目标吗?public class Rootobject{    public Company[] Companies { get; set; }}public class Company{    public string ORG_NAME { get; set; }    public SalesArea[] Salesareas { get; set; }    public Node[] Nodes { get; set; }    public EthernetArea[] Ethernetareas { get; set; }}public class SalesArea{    public string OBJ_NAME { get; set; }    public string AREA_CTYPE { get; set; }}public class Node{    public string OBJ_NAME { get; set; }    public object BUILDING { get; set; }}public class EthernetArea{    public string OBJ_NAME { get; set; }    public string AREA_CTYPE { get; set; }    public Product[] Products { get; set; }}public class Product{    public string BANDWIDTH_A { get; set; }    public string CONNECTION_TYPE { get; set; }}
查看完整描述

2 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

我确定应该有另一种方法来做到这一点,但无论如何,这就是我所做的......


如果我理解正确,您想要“非规范化”数据并将集合导出到 CSV。


我用了很多Select SelectMany和Join


var root = new Rootobject

    {

        Companies = new Company[] {

            new Company

        {

            ORG_NAME = "Co",

            Salesareas = new SalesArea[]{

            new SalesArea {

                OBJ_NAME = "Sa",

                AREA_CTYPE = "SaAr",

            }

        },

            Nodes = new Node[] {

            new Node {

                OBJ_NAME = "No",

                BUILDING = "NoBu"

            }

        },

            Ethernetareas = new EthernetArea[] {

            new EthernetArea {

                OBJ_NAME = "Et",

                AREA_CTYPE = "EtAr",

                Products = new Product[] {

                    new Product {

                        BANDWIDTH_A = "ProA",

                        CONNECTION_TYPE = "ProCon"

                    }

                }

            }

        }

        },

        new Company

        {

            ORG_NAME = "Co2",

            Salesareas = new SalesArea[]{

            new SalesArea {

                OBJ_NAME = "Sa2",

                AREA_CTYPE = "SaAr2",

            }

        },

            Nodes = new Node[] {

            new Node {

                OBJ_NAME = "No2",

                BUILDING = "NoBu2"

            }

        },

            Ethernetareas = new EthernetArea[] {

            new EthernetArea {

                OBJ_NAME = "Et2",

                AREA_CTYPE = "EtAr2",

                Products = new Product[] {

                    new Product {

                        BANDWIDTH_A = "ProA2",

                        CONNECTION_TYPE = "ProCon2"

                    },

                    new Product {

                        BANDWIDTH_A = "ProA3",

                        CONNECTION_TYPE = "ProCon3"

                    }

                }

            }

        }

        }

    }

    };


    var sas = root.Companies.SelectMany(x => x.Salesareas.Select(y => new { Company = x.ORG_NAME, SalesName = y.OBJ_NAME, SalesAreaType = y.AREA_CTYPE }));

    var nodes = root.Companies.SelectMany(x => x.Nodes.Select(y => new { Company = x.ORG_NAME, NodesName = y.OBJ_NAME, NodeBuilding = y.BUILDING }));

    var ethes = root.Companies.SelectMany(x => x.Ethernetareas.SelectMany(y => y.Products .Select(z => new { Company = x.ORG_NAME, EthernetName = y.OBJ_NAME, EthernetArea = y.AREA_CTYPE, BandwithA = z.BANDWIDTH_A, ConnnectionType = z.CONNECTION_TYPE })));


    sas.Join(nodes, x => x.Company, y => y.Company, (x, y) => new {x.Company, x.SalesName, x.SalesAreaType, y.NodesName, y.NodeBuilding})

        .Join(ethes, x => x.Company, y => y.Company, (x, y) => new {x.Company, x.SalesName, x.SalesAreaType, x.NodesName, x.NodeBuilding, y.EthernetName, y.EthernetArea, y.BandwithA, y.ConnnectionType})

        .Dump();

Dump()是一个LinqPad扩展方法

这是结果......

//img1.sycdn.imooc.com//6190b6100001ac5b12260289.jpg

查看完整回答
反对 回复 2021-11-14
?
慕标5832272

TA贡献1966条经验 获得超4个赞

定义一个类,该类将在 CSV 中表示您想要的内容。由于多个对象属性在您的模型中具有相同的名称。

在您的评论中,您选择使用类名作为属性的前缀,因此您应该具有以下内容:


public class CompanyCSV

{

    public string Company_ORG_NAME { get; set; }


    public string SalesArea_OBJ_NAME { get; set; }

    public string SalesArea_AREA_CTYPE { get; set; }


    public string Node_OBJ_NAME { get; set; }

    public string Node_BUILDING { get; set; }


    public string EthernetArea_OBJ_NAME { get; set; }

    public string EthernetArea_AREA_CTYPE { get; set; }


    public string Product_BANDWIDTH_A { get; set; }

    public string Product_CONNECTION_TYPE { get; set; }

}

然后简单地:


var result = from c in dataInput.Companies

                from s in c.Salesareas

                from n in c.Nodes

                from e in c.Ethernetareas

                from p in e.Products

                select new CompanyCSV

                {

                    Company_ORG_NAME = c.ORG_NAME,


                    SalesArea_OBJ_NAME = s.OBJ_NAME,

                    SalesArea_AREA_CTYPE = s.AREA_CTYPE,


                    Node_OBJ_NAME = n.OBJ_NAME,

                    Node_BUILDING = n.BUILDING.ToString(),


                    EthernetArea_OBJ_NAME = e.OBJ_NAME,

                    EthernetArea_AREA_CTYPE = e.AREA_CTYPE,


                    Product_BANDWIDTH_A = p.BANDWIDTH_A,

                    Product_CONNECTION_TYPE = p.CONNECTION_TYPE

                };



foreach (var line in result)

{ // Don't use this to generate your csv this is simply to show the result

    Console.WriteLine($"{line.c},{line.s},{line.n},{line.e},{line.p}, ..etc ..");

}

要编写您的 CSV,您可以使用CsvHelper。这将帮助您使用逗号或引号处理值。不要手动生成 CSV。


如果您的集合(节点 []、公司 [] 等)可以为空,您应该在 getter 中使用空合并运算符来保护这种边缘情况,例如:


private Node[] nodes;

public Node[] Nodes {

    get { return nodes ?? (nodes = new Node[] { }); }

    set { nodes = value; }

}


查看完整回答
反对 回复 2021-11-14
  • 2 回答
  • 0 关注
  • 269 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信