2017-01-05 1 views
0

Я использую FileHelpers DelimitedClassBuilder для создания класса на основе метаданных в datatable. Таким образом, я могу прочитать любой файл, известный в метаданных. Я читаю его как поток и обрабатываю каждую запись по отдельности. Для дальнейшей обработки я хочу добавить некоторые данные в данные и затем сериализовать их в JSON. Это добавление части поля, которая не работает. Поток возвращает объект. Я использую обход. Сериализация объекта в JSON, де-сериализация его в словаре, добавление полей, а затем сериализация его в JSON. Я уверен, что это можно сделать более эффективным способом. Я попытался преобразовать его в список, но это не работает.FileHelpers DelimitedClassBuilder добавлять поля после чтения

//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(); 

ответ

0

Вы можете использовать список полей, полученных путем отражения в классе записи. Затем используйте Linq's 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); 
    } 
} 
Смежные вопросы