在同一文件中循环 header 和详细记录

Looping header and details records in same file

我在下面重新编辑了这个问题我有一个示例文件,它是文件中的多个采购订单,由第二列标识。

Order Number, Purchase Number,DATE,Item Code ,Qty, Description 1245456,98978,12/01/2019, 1545-878, 1,"Test"

1245456,98978,12/01/2019,1545-342,2,"Test"

1245456,98978,12/01/2019,1545-878,2,"Test"

1245456,98979,12/02/2019,1545-878,3,"Test 3"

1245456,98979,12/02/2019,1545-342,4,"Test 4"

1245456,98979,12/02/2019,1545-878,5,"Test 4"

我想要的最终结果是能够将以上内容合二为一class,如下所示

最开始我正在使用 filelpers 来解析 csv 文件,如果我有 sep header 文件和行文件,这会很好用,但如您所见,它们是组合在一起的

var engine = new FileHelperEngine<CSVLines>();
var lines = engine.ReadFile(csvFileName);

所以 Class 应该如下所示

  [DelimitedRecord(",")]
  public class SalesOrderHeader
  {
     private Guid? _guid;


    public  Guid RowID
    {
        get
        {
            return _guid ?? (_guid = Guid.NewGuid()).GetValueOrDefault();
        }
    }
    public string DocReference { get; set; }
    public string CardCode { get; set; }
    public string DocDate { get; set; }
    public string ItemCode { get; set; }

    public string Description { get; set; }
    public string Qty { get; set; }

    public string Price { get; set; }


    [FieldHidden]
    public List<SalesOrderHeader> OrdersLines { get; set; }
  }

我想我要做的是两个循环,正如您从我的 createsales 订单例程中看到的那样,我首先创建 header,然后在其中添加行。

 public void CreateSalesOrder(List<SalesOrderHeader> _salesOrders)
    {
        foreach (var record in _salesOrders.GroupBy(g => g.DocReference))
        {

            // Init the Order object
            oOrder = (SAPbobsCOM.Documents)company.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oOrders);
            SAPbobsCOM.SBObob oBob;
            // set properties of the Order object
           // oOrder.NumAtCard = record.Where(w=>w.RowID = record.Where()
            oOrder.CardCode = record.First().CardCode;
            oOrder.DocDueDate = DateTime.Now;

            oOrder.DocDate =Convert.ToDateTime(record.First().DocDate);
            foreach (var recordItems in _salesOrders.SelectMany(e=>e.OrdersLines).Where(w=>w.DocReference ==record.First().DocReference))
            {
                oOrder.Lines.ItemCode = recordItems.ItemCode;
                oOrder.Lines.ItemDescription = recordItems.Description;
                oOrder.Lines.Quantity = Convert.ToDouble(recordItems.Qty);
                oOrder.Lines.Price = Convert.ToDouble(recordItems.Price);

                oOrder.Lines.Add();
                log.Debug(string.Format("Order Line added to sap Item Code={0}, Description={1},Qty={2}", recordItems.ItemCode, recordItems.Description, recordItems.Qty));

            }
            int lRetCode = oOrder.Add(); // Try to add the orer to the database
        }

        if(lRetCode == 0)
        {
            string body = "Purchase Order Imported into SAP";               
 
        }
        if (lRetCode != 0)
        {
            int temp_int = lErrCode;
            string temp_string = sErrMsg;
            company.GetLastError(out temp_int, out temp_string);
            if (lErrCode != -4006) // Incase adding an order failed
            {
                log.Error(string.Format("Error adding an order into sap ErrorCode {0},{1}", temp_int, temp_string));
            }

        }
    }

你会看到我遇到的问题是如何首先将 csv 分成两个列表,其次我如何在强类型 object 中正确访问 header 行,如你所见我先用,但不能正常使用。

对于 FileHelpers,重要的是避免将映射 class 用于描述底层文件结构以外的任何内容。在这里,我怀疑您正试图直接映射到太复杂的 class。

FileHelpers class 只是一种使用 C# 语法定义平面文件规范的方法。

因此,FileHelpers classes 是一种不常见的 C# class 类型,您不应尝试使用公认的 OOP 原则。 FileHelpers 不应具有超出 FileHelpers 库使用的属性或方法。

仅将 FileHelpers class 视为 CSV 格式的 'specification'。这应该是它唯一的作用。 (无论如何,从维护的角度来看,这是一个很好的做法 - 如果底层 CSV 结构发生变化,则更容易调整您的代码)。

然后如果你需要更多'normal'object中的记录,然后将结果映射到更好的东西,即封装了[的所有功能的class =13=] object 而不是 CSVOrder.

因此,处理此类文件的一种方法是对文件进行两次解析。在第一遍中,您提取 header 记录。像这样:

var engine1 = new FileHelperEngine<CSVHeaders>();
var headers = engine1.ReadFile(csvFileName);

在第二遍中提取细节;

var engine2 = new FileHelperEngine<CSVDetails>();
var details = engine2.ReadFile(csvFileName);

然后您将这些信息合并到一个新的专用 class 中,也许与此类似的一些 LINQ

var niceOrders = 
    headers
        .DistinctBy(h => h.OrderNumber)
            .SelectMany(d => details.Where(d => d.OrderNumber = y))
                 .Select(x => 
                      new NiceOrder() { 
                          OrderNumber = x.OrderNumber,  
                          Customer = x.Customer,
                          ItemCode = x.ItemCode                                     
                          // etc.
                      });