2012-01-03 52 views
0

我正在使用C#FileHelpers庫有效地將大型分隔文件解析爲驗證對象。將FileHelpers映射到多個輸出屬性

但是,我想能夠將單個輸入文件列映射到多個輸出類屬性,但找不到明顯的方法來實現此目的。我已經看過了ITransformable,但我不想在操作過程中映射到另一個減少內存的對象,並且我查看了DynamicFieldBuilder/DynamicClassBuilder對象,但這些對象似乎只允許我描述什麼是在輸入文件中,不是輸出實例中應該包含的內容。

我想避免不得不加載文件兩次或在事後做某種對象到對象的映射。

輸入文件示例:

ColumnA|ColumnB 
Foo|Baz 

輸出類示例:

public class FooBar 
{ 
    public string ColumnA_One; 
    public string ColumnA_Two; 
    public string ColumnB_One; 
    public string ColumnB_Two; 
} 
+0

你可以這樣做,如果你創建了一個枚舉和外來列上創建一個單獨的枚舉,以及這是否有道理枚舉將持有列的順序,如果不同的文件共享coulunm但在不同的順序。 。然後索引或通過順序位置來訪問它們當然是通過(int)然後枚舉字段名稱來看看我的示例如下 – MethodMan 2012-01-03 22:26:51

+0

這不是我想要做的。我想要一個像上面例子那樣的單個輸入文件來生成一個FooBar的實例,其中ColumnA_One和ColumnA_Two等於'Foo',而ColumnB_One和ColumnB_Two等於「Baz」。 – 2012-01-04 14:42:58

+0

是的,但看着CollumnA_One例如什麼是您想要的字段名稱..發送給我或給我一個所有字段的列表,我可以爲您構建一個枚舉示例..這將是很高興知道數據你正在使用的分隔符也適用於我的例子,我的5個不同的文件共享枚舉結構並以逗號作爲分隔符 – MethodMan 2012-01-04 14:44:47

回答

1

您可以標記與FieldIgnored attribute的重複列,並使用AfterReadRecord event,以填補他們。

class Program 
{ 
    [DelimitedRecord("|")] 
    public class FooBar 
    { 
     public string ColumnA_One;  
     [FieldIgnored] 
     public string ColumnA_Two;   

     public string ColumnB_One;   
     [FieldIgnored] 
     public string ColumnB_Two; 
    } 

    static void Main(string[] args) 
    { 
     FileHelperEngine engine = new FileHelperEngine(typeof(FooBar)); 
     engine.AfterReadRecord += engine_AfterReadRecord; 
     FooBar[] records = engine.ReadFile("FileIn.txt") as FooBar[]; 
    } 

    static void engine_AfterReadRecord(EngineBase engine, FileHelpers.Events.AfterReadEventArgs<object> e) 
    { 
     FooBar fooBar = e.Record as FooBar; 
     fooBar.ColumnA_Two = fooBar.ColumnA_One; 
     fooBar.ColumnB_Two = fooBar.ColumnB_One; 
    } 
} 
+0

這是有效的,我們嘗試了這種方法,但不幸的是它不是高性能的,因爲您最終會執行兩次處理;一次讀入記錄,並在每行之後再次將數據複製到另一列。 – 2012-01-12 16:17:38

+0

這是一個正確的答案,但是我們最終修補FileHelpers以包含[FieldRawValue]屬性,並且按照慣例,我們使用此屬性填充具有前一列未轉換值的任何屬性。 – 2012-01-12 16:18:55

0
enum DataFields 
    { 
     Action = 0, 
     CRC = 1, 
     Desc = 2, 
     Group = 3, 
     Name = 4, 
     Sell = 5, 
     EffDate = 6, 
     Whse = 7, 
     Whse2 = 8, 
     Whse3 = 9, 
     Casepack = 10, 
     LDU = 11, 
     Cube = 12, 
     Item = 13, 
     UPC = 14, 
     Cost = 15, 
     Markup = 16, 
     OldSell = 17, 
     Avail = 18, 
     Substitute = 19, 
     Poll = 20 
    }//enum DataFields 

    /// <summary> 
    /// This will hold the ordinal position of the NameFields within the datafile 
    /// </summary> 
    enum NameFields 
    { 
     Code = 0, 
     Abrv = 1, 
     Name = 2, 
     Count = 3 
    }//enum NameFields 

    /// <summary> 
    /// This will hold the ordinal position of the values when populating the history table 
    /// </summary> 
    enum HistoryFields 
    { 
     CRC = 0, 
     EffDate = 1, 
     OldSell = 2, 
     Sell = 3 
    }//enum HistoryFields 
    #endregion