如何使用FileHelpers返回完全填充的对象部分完整的数据? [英] How to return fully populated objects using FileHelpers for partially complete data?

查看:204
本文介绍了如何使用FileHelpers返回完全填充的对象部分完整的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有一个包含以下结构的CSV文件。

Assume you have a CSV file with the following structure

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

使用相应的 FileHelpers 定义类

[DelimitedRecord(",") ]
[IgnoreFirst(1)] 
public class Product
{
    public int ID { get; set; }
    public string Description { get; set; }

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

如何使用 FileHelpers ,以返回对象,以便每个对象完全填充?

How do use FileHelpers, to return objects such that each object is fully populated?

使用 engine.ReadFile 将只会从第2行和第5行生成完全填充的对象,这是有意义的,因为字段为空。但是,第3行和第4行的对象应该也具有与第1行相同的 ID 描述 Value 字段应保持不变。我不确定数据的正确术语是什么,但它似乎部分正常化。

Let me clarify, currently, result of using engine.ReadFile will only produce objects from Lines 2 and 5 as fully populated, which makes sense since the fields are blank. However, objects from Lines 3 and 4 should also have the same ID and Description as Line 1. The Value field should remain untouched for each line. I am not sure what the correct term for the data is, but it seems to 'partially normalised'.

我目前的方法解决这个问题如下使用 AfterRead 事件。我没有很好地掌握事件,事件处理程序,代表等,所以我正在寻找一个替代的方法来实现这个使用FileHelpers。

My current approach to solve this is as follows using the AfterRead event. I do not have a good grasp of Events, Event Handlers, delegates etc, so I am looking for an alternative way to achieve this using FileHelpers. It also seems very clunky.

    // call the csv repo using the ffg lines within a console app
    var repo2 = new CSVRepositoryBase<Product>();
    repo2.AfterRead +=new AfterReadHandler<object>(repo2_AfterRead);
    var products = repo2.Read("some file path");

    public static Product PreviousRecord { get; set; }

    private static void repo2_AfterRead
        (EngineBase engine, FileHelpers.Events.AfterReadEventArgs<object> e)
    {
        var record = (Product)e.Record;

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

        if (String.IsNullOrEmpty(record.ID)) // newline record = blank row
        {
            record.ID = PreviousRecord.ID;
        } 
        PreviousRecord.ID = record.ID;

    }


public class CSVRepositoryBase<T> where T : class
{
    // shorten for brevity 

    public IEnumerable<T> Read(string fileName){/*snip*/ }

    #region Events
    public event AfterReadHandler<object> AfterRead
    {
        add { engine.AfterReadRecord += value; }
        remove { engine.AfterReadRecord -= value; }
    }
    #endregion 
}


推荐答案

你可以尝试使用AfterRead的接口,而不是像这样的事件。

You can try using the interfaces for AfterRead instead of events like this.

如果我明白你需要做这样的事情:

If I understand right you need to do something like that:

[DelimitedRecord(",") ]
[IgnoreFirst(1)] 
public class Product
:INotifyRead
{
    public int? ID;
    public string Description;

    [FieldConverter(ConverterKind.Decimal)]
    public decimal? Val;

    private static Product Previuous;

    public void AfterRead(EngineBase engine, string line)
    {
        if (!ID.HasValue && Previous != null)
              this.ID = Previus.ID;

        if (!Val.HasValue && Previous != null)
              this.Val= Previus.Val;

        Previuous = this;
    }
}

希望这有助于

这篇关于如何使用FileHelpers返回完全填充的对象部分完整的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆