在同一文件中循环标题和详细信息记录

时间:2019-01-12 11:57:27

标签: c# filehelpers

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

  

订单号,采购号,日期,项目代码,数量,说明   1245456,98978,12 / 01/2019,1545-878,1,“测试”

     

1245456,98978,12 / 01 / 2019,1545-342,2,“测试”

     

1245456,98978,12 / 01 / 2019,1545-878,2,“测试”

     

1245456,98979,12 / 02 / 2019,1545-878,3,“测试3”

     

1245456,98979,12 / 02 / 2019,1545-342,4,“测试4”

     

1245456,98979,12 / 02 / 2019,1545-878,5,“测试4”

我希望最终结果是能够将上述内容放置在如下所示的一个类中

至少我要使用filelpers来解析csv文件,如果我有sep头文件和行文件,但是将它们合并在一起的话,这会很好地工作

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

所以班级应该像下面这样

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

我想我将要做的是两个循环,就像您从我的createales订单例程中看到的那样,我首先创建标题,然后在其中添加行。

 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分为两个列表,其次,如我所见,我将如何正确使用强类型对象中的标题行,这将无法正常工作。

1 个答案:

答案 0 :(得分:1)

使用FileHelpers,除了描述底层文件结构之外,避免将映射类用于任何其他事情很重要。在这里,我怀疑您正在尝试直接映射到过于复杂的类。

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

因此,FileHelpers类是C#类的不寻常类型,您不应尝试使用公认的OOP原则。 FileHelpers不应具有FileHelpers库所使用的属性或方法。

仅将FileHelpers类视为CSV格式的“规范”。那应该是它的唯一作用。 (无论如何,从维护的角度来看,这是一个好习惯-如果要更改基础CSV结构,则更容易修改您的代码。)

然后,如果您需要在更“正常”的对象中进行记录,则将结果映射到更好的东西,即,一个类封装了Order对象而不是{{1} }。

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

CSVOrder

在第二遍中,您提取详细信息;

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

然后,您可以将此信息组合到一个新的专用类中,也许可以使用与此类似的一些LINQ

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