tags:

views:

41

answers:

1

Assume you have a CSV file with the following simplified structure

 LINE1:  ID,Description,Value
 LINE2:  1,Product1,2
 LINE3:  ,,3
 LINE4:  ,,4
 LINE5:  2,Product2,2
 LINE6:  ,,3
 LINE7:  ,,5 

I am using FileHelpers to read the CSV and have hooked up one the interfaces that allows me me to access the current line, after it has been read. Refer to this SO question for more background.

The issues is that using that approach I will need to write many more if statements to check all the fields that need to be copied. (I have at least, 6 csv files at the moment with the same 'blank' format all having more than 20 fields that need to be copied ~ 120 if statements. urggh)

Now this is not a micro optimisation exercise since there will be more files that will have this 'incomplete' format.

How can I update the previous record in an elegant way such that I wont have to write if conditions and declarations for each field?

A: 

The current solution is to annotate the required fields using a custom attribute called CopyMe and then use reflection to copy.

[DelimitedRecord(",") ]
[IgnoreFirst(1)] 
public class Product
{

    [CopyMe()] public int ID { get; set; }
    [CopyMe()] public string Description { get; set; }

    [FieldConverter(ConverterKind.Decimal)]
    public decimal Val{ get; set; }
}

with the AfterRead method looking like so...

public void AfterRead(AfterReadEventArgs<RawVolsDataPoints> e)
{
    var record = (Product)e.Record;

    if (PreviousRecord == null)
    {
        PreviousRecord = new Product();
         PreviousRecord = record;
    }

    if (String.IsNullOrEmpty(record.ID)) // null value indicates a new row
    {
        var ttype = typeof(Product);
        var fields = ttype.GetFields();

        var fieldsToCopy = fields.Where(field =>
            field.GetCustomAttributes(typeof(CopyMeAttribute), true).Any());

        foreach (var item in fieldsToCopy)
        {
            var prevvalue = item.GetValue(PreviousRecord);
            item.SetValue(record, prevvalue);
         }
    }
}
Ahmad