简体   繁体   English

FileHelpers DelimitedClassBuilder阅读后添加字段

[英]FileHelpers DelimitedClassBuilder add fields after read

I'm using the FileHelpers DelimitedClassBuilder to build a class based on metadata in a datatable. 我正在使用FileHelpers DelimitedClassBuilder来基于数据表中的元数据构建一个类。 This way I can read any file known in the metadata. 这样,我可以读取元数据中已知的任何文件。 I read it as a stream and process each record individually. 我将其作为流读取,并分别处理每个记录。 For further processing I want to add some fields to the data and then serialize it to JSON. 为了进一步处理,我想向数据添加一些字段,然后将其序列化为JSON。 It's the adding of fields part that doesn't work. 这是添加字段的部分无效。 The stream returns an object. 流返回一个对象。 I'm using a work-around. 我正在使用一种解决方法。 Serializing the object to JSON, de-serializing it to a dictionary, adding the fields and then serializing it to JSON again. 将对象序列化为JSON,将其反序列化为字典,添加字段,然后再次将其序列化为JSON。 I'm sure this can be done in a more efficient way. 我相信这可以通过更有效的方式来完成。 I tried converting it to a list but that doesn't work. 我尝试将其转换为列表,但这不起作用。

//build runtime class based on metadata
FD.DelimitedClassBuilder cb = new FD.DelimitedClassBuilder("ImportFile", "|");
cb.IgnoreFirstLines = 1;
foreach (DT.DataRow drMetadata in dtMetadata.Rows)
{
    cb.AddField(drMetadata["EntityColumnName"].ToString(), typeof(string));
    cb.LastField.FieldQuoted = true;
    cb.LastField.QuoteMode = FH.QuoteMode.AlwaysQuoted;
    cb.LastField.QuoteMultiline = FH.MultilineMode.AllowForBoth;
}
//create async filehelper engine for row by row processing
FH.FileHelperAsyncEngine fhe = new FH.FileHelperAsyncEngine(cb.CreateRecordClass());

using (fhe.BeginReadStream(file))
{
    foreach(object record in fhe)
    {
        //convert object to list, doesn't work
        //SG.List<object> blaat = (record as SG.IEnumerable<object>).Cast<object>().ToList();

        //serialize record class to json
        string json = JS.JsonConvert.SerializeObject(record, JS.Formatting.Indented);
        //convert message to key-value dictionary
        SG.IDictionary<string, string> values = JS.JsonConvert.DeserializeObject<SG.IDictionary<string, string>>(json);

        values.Add("SourceSystem", messagesource);
        values.Add("SourceType", messagetype);

        string json2 = JS.JsonConvert.SerializeObject(values, JS.Formatting.Indented);

        SY.Console.WriteLine(json2);
    }
}
fhe.Close();

You can use a list of fields obtained via reflection on the record class. 您可以使用通过记录类的反射获得的字段列表。 Then use Linq's ToDictionary to populate your values . 然后使用Linq的ToDictionary填充values

var recordClass = cb.CreateRecordClass();
List<FieldInfo> fields = recordClass.GetFields().ToList();

FileHelperAsyncEngine fhe = new FileHelperAsyncEngine(recordClass);
using (fhe.BeginReadStream(file))
{
    foreach (var record in fhe)
    {
        IDictionary<string, object> values = fields.ToDictionary(x => x.Name, x => x.GetValue(record));

        values.Add("SourceSystem", "messagesource");
        values.Add("SourceType", "messagetype");

        string json = JsonConvert.SerializeObject(values, Formatting.Indented);

        Console.WriteLine(json);
    }
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM