2014-09-27 33 views
3

我曾希望使用動態類型的對象來寫入CSV文件。如何使用CsvHelper編寫從DynamicObject派生的類?

我在CsvWriter.WriteObject方法中收到'CsvHelper.CsvWriterException'消息:「沒有屬性映射爲'WpmExport.DynamicEntry'類型。」

這裏是我試圖使用類:

public class DynamicEntry : DynamicObject 
{ 
    private Dictionary<string, object> dictionary = new Dictionary<string, object>(); 

    public override bool TryGetMember(
     GetMemberBinder binder, out object result) 
    { 
     string name = binder.Name.ToLower(); 
     return dictionary.TryGetValue(name, out result); 
    } 

    public override bool TrySetMember(
     SetMemberBinder binder, object value) 
    { 
     dictionary[binder.Name.ToLower()] = value; 
     return true; 
    } 

    public override IEnumerable<string> GetDynamicMemberNames() 
    { 
     return dictionary.Keys.AsEnumerable(); 
    } 
} 

任何人只要有任何意見或工作的例子嗎? http://joshclose.github.io/CsvHelper/的文檔提示可能但不提供任何指導。

TIA

回答

3

功能尚不存在。您可以編寫dynamic而不是DynamicObject。你可以在這裏查看主題的主題。 https://github.com/JoshClose/CsvHelper/issues/187

當功能得到實現,我會更新與它的版本的答案。

更新

這個功能將在3.0可用。您目前可以試用NuGet的3.0-beta。

2

因爲我不能等3.0版(和CsvHelper.Excel支持它),我找到了一個臨時解決方案。

取類出口:

public partial class EntryReportInventory 
{ 
    public Guid DeviceId { get; set; } 
    [ReportProperty] 
    public string DeviceName { get; set; } 

    public Dictionary<string, object> InventoryValues { get; set; } 

    public EntryReportInventory(Device device, Dictionary<string, object> inventoryValues) 
    { 
     this.DeviceId = device.Id; 
     this.DeviceName = device.Name; 

     this.InventoryValues = inventoryValues; 
    } 
} 

創建映射:

Type genericClass = typeof(DefaultCsvClassMap<>); 
Type constructedClass = genericClass.MakeGenericType(typeof(EntryReportInventory)); 
       return (CsvClassMap)Activator.CreateInstance(constructedClass); 

而現在的魔術。我遍歷所有的屬性。

foreach (PropertyInfo property in mapping) 
      { 
... 
if (isInventoryReportBaseType && typeof(Dictionary<string, object>).IsAssignableFrom(property.PropertyType)) 
       { 
        var dataSource = (ReportInventoryBase)Activator.CreateInstance(entityType, dbContext); 

        foreach (var item in dataSource.ColumnNameAndText) 
        { 
         var columnName = item.Key; 

         var newMap = new CsvPropertyMap(property); 
         newMap.Name(columnName); 
         newMap.TypeConverter(new InventoryEntryListSpecifiedTypeConverter(item.Key)); 

         customMap.PropertyMaps.Add(newMap); 
        } 
... 
} 

我的轉換器:

public class InventoryEntryListSpecifiedTypeConverter : CsvHelper.TypeConversion.ITypeConverter 
    { 
     private string indexKey; 
     public InventoryEntryListSpecifiedTypeConverter(string indexKey) 
     { 
      this.indexKey = indexKey; 
     } 

     public bool CanConvertFrom(Type type) 
     { 
      return true; 
     } 

     public bool CanConvertTo(Type type) 
     { 
      return true; 
     } 

     public object ConvertFromString(TypeConverterOptions options, string text) 
     { 
      throw new NotImplementedException(); 
     } 

     public string ConvertToString(TypeConverterOptions options, object value) 
     { 
      var myValue = value as Dictionary<string, object>; 
      if (value == null || myValue.Count == 0) return null; 

      return myValue[indexKey] + ""; 
     } 
    } 

不知道爲什麼,但它的作品好幾次經過相同的屬性。 就是這樣:) 你只需要有一個列表(這裏:dataSource.ColumnNameAndText,從外部來源填充)來標識列/值。

相關問題