我在下面重新编辑了这个问题,我有一个示例文件,该文件作为第二栏中标识的文件中的多个采购订单。
订单号,采购号,日期,项目代码,数量,说明 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分为两个列表,其次,如我所见,我将如何正确使用强类型对象中的标题行,这将无法正常工作。
答案 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);